fix gitlab tests
This commit is contained in:
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class AttendanceAutoPublishCommand extends Command
|
||||
{
|
||||
protected $signature = 'attendance:auto-publish';
|
||||
|
||||
protected $description = 'Auto-publish attendance days per "second Sunday backward" rule.';
|
||||
|
||||
public function handle(AttendanceAutoPublishJobService $service): int
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class CheckMissedPaymentsCommand extends Command
|
||||
{
|
||||
protected $signature = 'payments:check-missed';
|
||||
|
||||
protected $description = 'Checks for users who missed payments and sends reminders.';
|
||||
|
||||
public function handle(PaymentMissedCheckService $service): int
|
||||
@@ -16,7 +15,6 @@ class CheckMissedPaymentsCommand extends Command
|
||||
$users = $service->findUsersWithMissedPayments();
|
||||
if (empty($users)) {
|
||||
$this->info('No missed payments found.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class CleanupExpiredNotificationsCommand extends Command
|
||||
{
|
||||
protected $signature = 'notifications:cleanup';
|
||||
|
||||
protected $description = 'Deletes expired notifications from the database.';
|
||||
|
||||
public function handle(NotificationCleanupService $service): int
|
||||
@@ -17,7 +16,6 @@ class CleanupExpiredNotificationsCommand extends Command
|
||||
|
||||
if ($count <= 0) {
|
||||
$this->info('No expired notifications found to soft delete.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class CleanupPasswordResetsCommand extends Command
|
||||
{
|
||||
protected $signature = 'cleanup:password-resets {--days=30}';
|
||||
|
||||
protected $description = 'Delete password reset requests older than N days.';
|
||||
|
||||
public function handle(PasswordResetCleanupService $service): int
|
||||
|
||||
@@ -9,7 +9,6 @@ use Illuminate\Console\Command;
|
||||
class ConfigUpdateCommand extends Command
|
||||
{
|
||||
protected $signature = 'config:update {task?} {--task=} {--dry} {--force} {--tz=}';
|
||||
|
||||
protected $description = 'Run a configuration update task (weekly cron).';
|
||||
|
||||
public function handle(ConfigUpdateService $service): int
|
||||
@@ -22,14 +21,12 @@ class ConfigUpdateCommand extends Command
|
||||
|
||||
if ($task === '' || !in_array($task, $service->availableTasks(), true)) {
|
||||
$this->error('Invalid or missing --task. Available: ' . implode(', ', $service->availableTasks()));
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$result = $service->runTask($task, $dry, $force, $tz);
|
||||
if (!$result['ok']) {
|
||||
$this->error($result['message'] ?? "Task '{$task}' failed.");
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class DeleteInactiveUsersCommand extends Command
|
||||
{
|
||||
protected $signature = 'users:delete-inactive-users {--minutes=15}';
|
||||
|
||||
protected $description = 'Delete users that are inactive and created more than N minutes ago.';
|
||||
|
||||
public function handle(InactiveUserCleanupService $service): int
|
||||
|
||||
@@ -10,7 +10,6 @@ use Illuminate\Support\Facades\Event;
|
||||
class DeleteUnverifiedUsersCommand extends Command
|
||||
{
|
||||
protected $signature = 'users:delete-unverified {--timeout=86400}';
|
||||
|
||||
protected $description = 'Delete unverified users older than the configured timeout (seconds).';
|
||||
|
||||
public function handle(): int
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class RecalculateAttendanceCommand extends Command
|
||||
{
|
||||
protected $signature = 'attendance:recalculate-summary';
|
||||
|
||||
protected $description = 'Recalculates the attendance summary records from raw attendance data.';
|
||||
|
||||
public function handle(AttendanceSummaryRebuildService $service): int
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class SendAbsenteesSummaryCommand extends Command
|
||||
{
|
||||
protected $signature = 'attendance:absentees-summary';
|
||||
|
||||
protected $description = 'Sends daily attendance summaries for absences to parents.';
|
||||
|
||||
public function handle(AttendanceDailySummaryService $service): int
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class SendLatesSummaryCommand extends Command
|
||||
{
|
||||
protected $signature = 'attendance:lates-summary';
|
||||
|
||||
protected $description = 'Sends daily attendance summaries for lates to parents.';
|
||||
|
||||
public function handle(AttendanceDailySummaryService $service): int
|
||||
|
||||
@@ -9,7 +9,6 @@ use Illuminate\Console\Command;
|
||||
class SendMonthlyPaymentNotificationsCommand extends Command
|
||||
{
|
||||
protected $signature = 'payments:monthly-reminder {--force} {--email=} {--type=}';
|
||||
|
||||
protected $description = 'Send monthly payment reminders on the first Saturday of every month.';
|
||||
|
||||
public function handle(PaymentNotificationService $service): int
|
||||
@@ -22,7 +21,6 @@ class SendMonthlyPaymentNotificationsCommand extends Command
|
||||
$user = User::query()->where('email', $email)->first();
|
||||
if (!$user) {
|
||||
$this->error('Invalid --email provided.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
@@ -33,13 +31,11 @@ class SendMonthlyPaymentNotificationsCommand extends Command
|
||||
]);
|
||||
|
||||
$this->info('Test reminder sent for ' . $email . '.');
|
||||
|
||||
return $result['failed'] > 0 ? self::FAILURE : self::SUCCESS;
|
||||
}
|
||||
|
||||
if (!$force && !$this->isFirstSaturday(now())) {
|
||||
$this->info('Not the first Saturday of the month. Use --force to override.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class SendTestPaymentNotificationCommand extends Command
|
||||
{
|
||||
protected $signature = 'payments:send-test {--email=} {--type=no_payment}';
|
||||
|
||||
protected $description = 'Send a single test non-payment or installment reminder to a specific email.';
|
||||
|
||||
public function handle(PaymentTestNotificationService $service): int
|
||||
@@ -18,14 +17,12 @@ class SendTestPaymentNotificationCommand extends Command
|
||||
|
||||
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$this->error('Usage: php artisan payments:send-test --email=addr@example.com [--type=no_payment|installment]');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$result = $service->send($email, $type);
|
||||
if (!$result['ok']) {
|
||||
$this->error('Failed to send test reminder to ' . $email . '.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ use Illuminate\Console\Command;
|
||||
class SyncPaypalPaymentsCommand extends Command
|
||||
{
|
||||
protected $signature = 'payments:sync-paypal {--dry-run} {--report-only}';
|
||||
|
||||
protected $description = 'Sync PayPal payments to internal payments table from paypal_payments.';
|
||||
|
||||
public function handle(PaypalPaymentSyncService $service): int
|
||||
|
||||
@@ -4,5 +4,7 @@ namespace App\Events;
|
||||
|
||||
class DeleteUnverifiedUser
|
||||
{
|
||||
public function __construct(public int $userId) {}
|
||||
public function __construct(public int $userId)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,7 @@ class WhatsappInvitesSend
|
||||
use Dispatchable;
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct(public array $payload) {}
|
||||
public function __construct(public array $payload)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@ if (! function_exists('local_date')) {
|
||||
{
|
||||
try {
|
||||
$carbon = CarbonImmutable::parse($utcDateTime)->setTimezone(config('app.timezone'));
|
||||
|
||||
return $carbon->format($format);
|
||||
} catch (Throwable $e) {
|
||||
} catch (\Throwable $e) {
|
||||
return CarbonImmutable::parse($utcDateTime)->format($format);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +62,6 @@ if (! function_exists('pbkdf2_verify')) {
|
||||
}
|
||||
|
||||
$calc = hash_pbkdf2($algo, $password, $salt, (int) $iterations, strlen($derived), true);
|
||||
|
||||
return hash_equals($derived, $calc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ class AdministratorAbsenceController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AdministratorAbsenceService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
|
||||
@@ -11,7 +11,8 @@ class AdministratorDashboardController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AdministratorDashboardService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function metrics(): JsonResponse
|
||||
{
|
||||
|
||||
@@ -14,7 +14,8 @@ class AdministratorEnrollmentController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AdministratorEnrollmentService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
@@ -12,7 +12,8 @@ class AdministratorNotificationController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AdministratorNotificationService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function alerts(): JsonResponse
|
||||
{
|
||||
|
||||
@@ -16,18 +16,18 @@ use App\Http\Resources\Promotions\PromotionReminderResource;
|
||||
use App\Http\Resources\Promotions\StudentPromotionResource;
|
||||
use App\Models\PromotionAuditLog;
|
||||
use App\Models\PromotionReminderLog;
|
||||
use App\Models\SectionPlacementBatch;
|
||||
use App\Models\StudentPromotionRecord;
|
||||
use App\Services\Promotions\LevelProgressionService;
|
||||
use App\Services\Promotions\Placement\SectionPlacementPreviewService;
|
||||
use App\Services\Promotions\PromotionAuditService;
|
||||
use App\Services\Promotions\PromotionEligibilityService;
|
||||
use App\Services\Promotions\PromotionEnrollmentService;
|
||||
use App\Services\Promotions\PromotionQueryService;
|
||||
use App\Services\Promotions\PromotionReminderService;
|
||||
use App\Services\Promotions\PromotionStatusService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Services\Promotions\Placement\SectionPlacementPreviewService;
|
||||
use App\Models\SectionPlacementBatch;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -54,7 +54,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function index(AdminListPromotionsRequest $request): JsonResponse
|
||||
{
|
||||
$result = $this->query->list($request->filters());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => StudentPromotionResource::collection($result['data']),
|
||||
@@ -74,7 +73,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
if ($record instanceof JsonResponse) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => new StudentPromotionResource($this->query->detail($record)),
|
||||
@@ -84,7 +82,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function summary(AdminListPromotionsRequest $request): JsonResponse
|
||||
{
|
||||
$counts = $this->query->countsByStatus($request->filters());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'counts_by_status' => $counts,
|
||||
@@ -128,7 +125,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
};
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Promotion eligibility evaluation failed', ['exception' => $e]);
|
||||
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Failed to evaluate promotion eligibility.',
|
||||
@@ -141,6 +137,7 @@ class AdministratorPromotionController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function createPlacementPreview(Request $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validate([
|
||||
@@ -160,7 +157,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Section placement preview generation failed', ['exception' => $e]);
|
||||
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => $e->getMessage(),
|
||||
@@ -192,7 +188,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
$batch = $this->sectionPlacement->finalize($batchId, $this->getCurrentUserId());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Section placement finalization failed', ['batch_id' => $batchId, 'exception' => $e]);
|
||||
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => $e->getMessage(),
|
||||
@@ -310,7 +305,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
'promotion_id' => $promotionId,
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Failed to send reminder.',
|
||||
@@ -327,7 +321,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
$result = $this->reminders->dispatchScheduledReminders(null, $userId);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'result' => $result,
|
||||
@@ -344,7 +337,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
->forPromotion((int) $record->getKey())
|
||||
->orderByDesc('id')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'reminders' => PromotionReminderResource::collection($rows),
|
||||
@@ -361,7 +353,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
->forPromotion((int) $record->getKey())
|
||||
->orderByDesc('id')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'entries' => PromotionAuditLogResource::collection($rows),
|
||||
@@ -371,7 +362,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function expireDeadlines(): JsonResponse
|
||||
{
|
||||
$result = $this->enrollmentService->markExpiredDeadlines(null, $this->getCurrentUserId());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'result' => $result,
|
||||
@@ -414,7 +404,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function levelProgressions(): JsonResponse
|
||||
{
|
||||
$rows = $this->progression->list(false);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'levels' => LevelProgressionResource::collection($rows),
|
||||
@@ -424,7 +413,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function upsertLevelProgression(UpsertLevelProgressionRequest $request): JsonResponse
|
||||
{
|
||||
$row = $this->progression->upsertMapping($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'level' => new LevelProgressionResource($row),
|
||||
@@ -434,7 +422,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
public function seedLevelProgressions(): JsonResponse
|
||||
{
|
||||
$created = $this->progression->seedDefaults();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'created' => $created,
|
||||
@@ -450,7 +437,6 @@ class AdministratorPromotionController extends BaseApiController
|
||||
'message' => 'Promotion record not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ class AdministratorTeacherSubmissionController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AdministratorTeacherSubmissionService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
@@ -18,7 +18,8 @@ class EmergencyContactController extends Controller
|
||||
public function __construct(
|
||||
private EmergencyContactDirectoryService $directoryService,
|
||||
private EmergencyContactCrudService $crudService
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
@@ -61,6 +61,9 @@ class TeacherClassAssignmentController extends BaseApiController
|
||||
], $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -14,7 +14,8 @@ class AttendanceCommentTemplateController extends Controller
|
||||
public function __construct(
|
||||
protected AttendanceCommentTemplateService $service,
|
||||
protected ApplicationUrlService $urls,
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function bootstrapUrls(): JsonResponse
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@ class LateSlipLogsController extends BaseApiController
|
||||
$deleted = $this->commandService->delete($log);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Late slip log delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to delete late slip log.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,9 @@ class TeacherAttendanceApiController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -41,9 +41,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'reason' => ['nullable', 'string', 'max:255'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['event' => $this->service->manualEntry($validator->validated(), $request->user())], 'Manual attendance entry recorded.', Response::HTTP_CREATED);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@@ -65,9 +63,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'authorized' => ['nullable'],
|
||||
'reason' => ['nullable', 'string', 'max:255'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['event' => $this->service->badgeScan($validator->validated(), $request->user())], 'Badge scan classified.');
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@@ -95,9 +91,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'reason' => ['nullable', 'string', 'max:255'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['event' => $this->service->exitEntry($validator->validated(), $request->user())], 'Exit attendance entry recorded.', Response::HTTP_CREATED);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@@ -119,9 +113,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'report_status' => ['nullable', 'string', 'max:48'],
|
||||
'reason' => ['nullable', 'string', 'max:255'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['event' => $this->service->markAbsent($validator->validated(), $request->user())], 'Absence recorded.', Response::HTTP_CREATED);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
@@ -138,9 +130,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'final_decision' => ['nullable', 'string', 'max:255'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['event' => $this->service->completeFollowUp($id, $validator->validated(), $request->user())], 'Follow-up completed.');
|
||||
} catch (\RuntimeException $e) {
|
||||
@@ -157,9 +147,7 @@ class AttendanceManagementController extends BaseApiController
|
||||
'slip_number' => ['nullable', 'string', 'max:64'],
|
||||
'late_slip_log_id' => ['nullable', 'integer'],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
if ($validator->fails()) return $this->respondValidationError($validator->errors()->toArray());
|
||||
try {
|
||||
return $this->success(['reprint' => $this->service->reprintLateSlip($id, $validator->validated(), $request->user())], 'Late slip reprint logged.', Response::HTTP_CREATED);
|
||||
} catch (\RuntimeException $e) {
|
||||
|
||||
@@ -12,7 +12,8 @@ class AttendanceTrackingController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected AttendanceTrackingService $service
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function pendingViolations(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
@@ -68,7 +68,6 @@ class IpBanController extends BaseApiController
|
||||
$ban = $this->commandService->banNow($id ? (int) $id : null, $ip ? (string) $ip : null, $hours);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('IP ban failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to ban IP.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -91,7 +90,6 @@ class IpBanController extends BaseApiController
|
||||
try {
|
||||
if ($all) {
|
||||
$count = $this->commandService->unbanAll();
|
||||
|
||||
return $this->success([
|
||||
'count' => $count,
|
||||
], $count . ' IP(s) unbanned.');
|
||||
@@ -103,7 +101,6 @@ class IpBanController extends BaseApiController
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('IP unban failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to unban IP.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Http\Controllers\Api\Auth;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Auth\RegisterRequest;
|
||||
use App\Http\Resources\Auth\RegisterResource;
|
||||
use App\Services\Auth\ApiRegistrationService;
|
||||
use App\Services\Auth\RegistrationCaptchaService;
|
||||
@@ -51,7 +50,7 @@ class RegisterController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), RegisterRequest::ruleset());
|
||||
$validator = Validator::make($request->all(), \App\Http\Requests\Auth\RegisterRequest::ruleset());
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
|
||||
@@ -71,7 +71,6 @@ class RolePermissionController extends BaseApiController
|
||||
$role = $this->roleCrudService->create($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role store failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to create role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -91,7 +90,6 @@ class RolePermissionController extends BaseApiController
|
||||
$role = $this->roleCrudService->update($role, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -111,7 +109,6 @@ class RolePermissionController extends BaseApiController
|
||||
$this->roleCrudService->delete($role);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to delete role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -148,7 +145,6 @@ class RolePermissionController extends BaseApiController
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Assign roles failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update roles.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -188,7 +184,6 @@ class RolePermissionController extends BaseApiController
|
||||
$permission = $this->permissionCrudService->create($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission store failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to create permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -208,7 +203,6 @@ class RolePermissionController extends BaseApiController
|
||||
$permission = $this->permissionCrudService->update($permission, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -228,7 +222,6 @@ class RolePermissionController extends BaseApiController
|
||||
$this->permissionCrudService->delete($permission);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to delete permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -250,13 +243,15 @@ class RolePermissionController extends BaseApiController
|
||||
$this->permissionService->saveRolePermissions($roleId, $request->validated()['permissions'] ?? []);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role permissions update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update role permissions.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
return $this->success(null, 'Permissions saved successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -6,9 +6,9 @@ use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Roles\RoleSwitchRequest;
|
||||
use App\Services\Roles\RoleSwitchService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RoleSwitcherController extends BaseApiController
|
||||
{
|
||||
@@ -56,6 +56,9 @@ class RoleSwitcherController extends BaseApiController
|
||||
], 'Role switched successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -19,7 +19,8 @@ class SessionTimeoutController extends Controller
|
||||
|
||||
public function __construct(
|
||||
private ApplicationUrlService $urls,
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timeout metadata for the web portal.
|
||||
|
||||
@@ -17,7 +17,8 @@ class BadgeController extends Controller
|
||||
protected BadgePdfService $badgePdfService,
|
||||
protected BadgePrintLogService $badgePrintLogService,
|
||||
protected BadgeFormDataService $badgeFormDataService
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function generatePdf(Request $request)
|
||||
{
|
||||
@@ -207,6 +208,9 @@ class BadgeController extends Controller
|
||||
return array_values(array_filter($ids, static fn ($v) => $v > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -4,4 +4,6 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController as CoreBaseApiController;
|
||||
|
||||
class BaseApiController extends CoreBaseApiController {}
|
||||
class BaseApiController extends CoreBaseApiController
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,16 +20,15 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
class ClassPreparationController extends BaseApiController
|
||||
{
|
||||
private ClassPreparationService $service;
|
||||
|
||||
private StickerCountService $stickerCounts;
|
||||
|
||||
private ClassRosterService $roster;
|
||||
|
||||
public function __construct(
|
||||
ClassPreparationService $service,
|
||||
StickerCountService $stickerCounts,
|
||||
ClassRosterService $roster
|
||||
) {
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->service = $service;
|
||||
$this->stickerCounts = $stickerCounts;
|
||||
@@ -79,7 +78,6 @@ class ClassPreparationController extends BaseApiController
|
||||
$count = $this->service->saveAdjustments($classSectionId, $schoolYear, $validated['adjustments']);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Class prep adjustment save failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to save adjustments.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ class ClassProgressController extends BaseApiController
|
||||
|
||||
if (!empty($filters['group_by_week'])) {
|
||||
$grouped = ClassProgressGroupCollection::fromPaginator($paginator);
|
||||
|
||||
return $this->respondSuccess($grouped, 'Progress reports retrieved.');
|
||||
}
|
||||
|
||||
@@ -136,7 +135,6 @@ class ClassProgressController extends BaseApiController
|
||||
Log::error('Failed to create class progress reports.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return $this->respondError('Unable to save progress reports.', 500);
|
||||
}
|
||||
|
||||
@@ -172,7 +170,6 @@ class ClassProgressController extends BaseApiController
|
||||
Log::error('Failed to update class progress report.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return $this->respondError('Unable to update progress report.', 500);
|
||||
}
|
||||
|
||||
@@ -187,7 +184,6 @@ class ClassProgressController extends BaseApiController
|
||||
Log::error('Failed to delete class progress report.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return $this->respondError('Unable to delete progress report.', 500);
|
||||
}
|
||||
|
||||
@@ -211,7 +207,6 @@ class ClassProgressController extends BaseApiController
|
||||
}
|
||||
|
||||
$downloadName = $record->original_name ?: basename($path);
|
||||
|
||||
return response()->download($path, $downloadName);
|
||||
}
|
||||
|
||||
@@ -233,6 +228,7 @@ class ClassProgressController extends BaseApiController
|
||||
|
||||
/**
|
||||
* @param mixed $user
|
||||
* @return User|JsonResponse
|
||||
*/
|
||||
private function requireAuthenticatedUser($user): User|JsonResponse
|
||||
{
|
||||
|
||||
@@ -126,7 +126,6 @@ class ClassController extends BaseApiController
|
||||
$created = $this->seedService->seedDefaults();
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Seeding default classes failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to seed default classes.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,13 +14,9 @@ use Illuminate\Http\Request;
|
||||
class CommunicationController extends BaseApiController
|
||||
{
|
||||
private CommunicationStudentService $students;
|
||||
|
||||
private CommunicationTemplateService $templates;
|
||||
|
||||
private CommunicationFamilyService $families;
|
||||
|
||||
private CommunicationPreviewService $previewService;
|
||||
|
||||
private CommunicationSendService $sendService;
|
||||
|
||||
public function __construct(
|
||||
@@ -180,13 +176,14 @@ class CommunicationController extends BaseApiController
|
||||
$user = auth()->user();
|
||||
if ($user) {
|
||||
$name = trim(($user->firstname ?? '') . ' ' . ($user->lastname ?? ''));
|
||||
|
||||
return $name !== '' ? $name : 'Teacher';
|
||||
}
|
||||
|
||||
return 'Teacher';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -14,11 +14,8 @@ use Illuminate\Http\Request;
|
||||
class CompetitionScoresController extends BaseApiController
|
||||
{
|
||||
private CompetitionScoresContextService $contextService;
|
||||
|
||||
private CompetitionScoresQueryService $queryService;
|
||||
|
||||
private CompetitionScoresRosterService $rosterService;
|
||||
|
||||
private CompetitionScoresSaveService $saveService;
|
||||
|
||||
public function __construct(
|
||||
@@ -225,6 +222,9 @@ class CompetitionScoresController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -17,8 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
class BaseApiController extends Controller
|
||||
{
|
||||
protected Request $laravelRequest;
|
||||
|
||||
protected ?ValidatorContract $validator = null;
|
||||
protected ValidatorContract|null $validator = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -93,7 +91,6 @@ class BaseApiController extends Controller
|
||||
{
|
||||
$payload = $this->payloadData();
|
||||
$errors = $this->validateRequest($payload, $rules);
|
||||
|
||||
return empty($errors);
|
||||
}
|
||||
|
||||
@@ -103,7 +100,6 @@ class BaseApiController extends Controller
|
||||
if (is_array($json)) {
|
||||
return $json;
|
||||
}
|
||||
|
||||
return array_merge($this->laravelRequest->query->all(), $this->laravelRequest->request->all());
|
||||
}
|
||||
|
||||
@@ -121,87 +117,70 @@ class BaseApiController extends Controller
|
||||
}
|
||||
if (preg_match('/^max_length\\[(\\d+)\\]$/', $part, $m)) {
|
||||
$result[] = 'max:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^min_length\\[(\\d+)\\]$/', $part, $m)) {
|
||||
$result[] = 'min:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^in_list\\[(.+)\\]$/', $part, $m)) {
|
||||
$result[] = 'in:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^greater_than_equal_to\\[(.+)\\]$/', $part, $m)) {
|
||||
$result[] = 'gte:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^less_than_equal_to\\[(.+)\\]$/', $part, $m)) {
|
||||
$result[] = 'lte:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^valid_date\\[(.+)\\]$/', $part, $m)) {
|
||||
$result[] = 'date_format:' . $m[1];
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'valid_email') {
|
||||
$result[] = 'email';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'permit_empty') {
|
||||
$result[] = 'nullable';
|
||||
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^is_unique\\[([^\\.]+)\\.([^\\]]+)\\]$/', $part, $m)) {
|
||||
$result[] = 'unique:' . $m[1] . ',' . $m[2];
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'string') {
|
||||
$result[] = 'string';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'integer') {
|
||||
$result[] = 'integer';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'numeric') {
|
||||
$result[] = 'numeric';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'required') {
|
||||
$result[] = 'required';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'alpha_numeric') {
|
||||
$result[] = 'alpha_num';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'in_array') {
|
||||
$result[] = 'in_array';
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($part === 'valid_url') {
|
||||
$result[] = 'url';
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strpos($part, 'max_size') === 0) {
|
||||
$result[] = str_replace('max_size', 'max', $part);
|
||||
|
||||
continue;
|
||||
}
|
||||
$result[] = $part;
|
||||
@@ -216,7 +195,7 @@ class BaseApiController extends Controller
|
||||
$perPage = max(1, $perPage);
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
if ($source instanceof EloquentBuilder || $source instanceof Builder) {
|
||||
if ($source instanceof EloquentBuilder || $source instanceof \Illuminate\Database\Query\Builder) {
|
||||
$total = $source->toBase()->getCountForPagination();
|
||||
$items = $source->offset($offset)->limit($perPage)->get()->toArray();
|
||||
} elseif (is_array($source)) {
|
||||
@@ -254,7 +233,6 @@ class BaseApiController extends Controller
|
||||
if ($userId <= 0) {
|
||||
$userId = (int) (optional($this->laravelRequest->user())->id ?? 0);
|
||||
}
|
||||
|
||||
return $userId > 0 ? $userId : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,8 @@ use Illuminate\Http\JsonResponse;
|
||||
class DiscountController extends BaseApiController
|
||||
{
|
||||
private DiscountContextService $context;
|
||||
|
||||
private DiscountVoucherService $voucherService;
|
||||
|
||||
private DiscountParentService $parentService;
|
||||
|
||||
private DiscountApplyService $applyService;
|
||||
|
||||
public function __construct(
|
||||
@@ -72,7 +69,6 @@ class DiscountController extends BaseApiController
|
||||
public function listVouchers(): JsonResponse
|
||||
{
|
||||
$vouchers = $this->voucherService->listAll();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'vouchers' => DiscountVoucherResource::collection($vouchers),
|
||||
@@ -82,7 +78,6 @@ class DiscountController extends BaseApiController
|
||||
public function storeVoucher(StoreDiscountVoucherRequest $request): JsonResponse
|
||||
{
|
||||
$voucher = $this->voucherService->create($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'voucher' => new DiscountVoucherResource($voucher),
|
||||
@@ -92,7 +87,6 @@ class DiscountController extends BaseApiController
|
||||
public function updateVoucher(UpdateDiscountVoucherRequest $request, int $id): JsonResponse
|
||||
{
|
||||
$voucher = $this->voucherService->update($id, $request->validated());
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'voucher' => new DiscountVoucherResource($voucher),
|
||||
@@ -102,7 +96,6 @@ class DiscountController extends BaseApiController
|
||||
public function showVoucher(int $id): JsonResponse
|
||||
{
|
||||
$voucher = $this->voucherService->find($id);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'voucher' => new DiscountVoucherResource($voucher),
|
||||
@@ -112,12 +105,14 @@ class DiscountController extends BaseApiController
|
||||
public function deleteVoucher(int $id): JsonResponse
|
||||
{
|
||||
$this->voucherService->delete($id);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -14,13 +14,9 @@ use Illuminate\Http\Request;
|
||||
class BroadcastEmailController extends BaseApiController
|
||||
{
|
||||
private BroadcastEmailSenderOptionsService $senderOptions;
|
||||
|
||||
private BroadcastEmailRecipientService $recipients;
|
||||
|
||||
private BroadcastEmailComposerService $composer;
|
||||
|
||||
private BroadcastEmailDispatchService $dispatch;
|
||||
|
||||
private BroadcastEmailImageService $imageService;
|
||||
|
||||
public function __construct(
|
||||
@@ -178,7 +174,6 @@ class BroadcastEmailController extends BaseApiController
|
||||
foreach (explode(',', $value) as $piece) {
|
||||
$ids[] = (int) $piece;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
$ids[] = (int) $value;
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Http\Resources\Email\EmailExtractorCompareResource;
|
||||
use App\Http\Resources\Email\EmailExtractorEmailsResource;
|
||||
use App\Services\Email\EmailExtractorService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EmailExtractorController extends BaseApiController
|
||||
{
|
||||
|
||||
@@ -113,6 +113,9 @@ class ExamDraftController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -51,7 +51,6 @@ class ExpenseController extends BaseApiController
|
||||
$rows = $this->queryService->listAll();
|
||||
$rows = array_map(function ($row) {
|
||||
$row['receipt_url'] = $this->receiptService->receiptUrl($row['receipt_path'] ?? null);
|
||||
|
||||
return $row;
|
||||
}, $rows);
|
||||
|
||||
@@ -191,6 +190,9 @@ class ExpenseController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -151,6 +151,9 @@ class ExtraChargesController extends BaseApiController
|
||||
], $ok ? 200 : 422);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -94,7 +94,6 @@ class FamilyAdminController extends BaseApiController
|
||||
|
||||
if (!$ok) {
|
||||
Log::warning('Compose email failed for family admin', ['recipient' => $payload['recipient']]);
|
||||
|
||||
return $this->error('Unable to send email.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ class FamilyController extends BaseApiController
|
||||
$result = $this->mutationService->bootstrapFamilies();
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Family bootstrap failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Family bootstrap failed.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -90,7 +89,6 @@ class FamilyController extends BaseApiController
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Attach guardian by email failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to attach guardian.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -159,7 +157,6 @@ class FamilyController extends BaseApiController
|
||||
$result = $this->mutationService->importSecondParentsFromLegacy();
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Legacy second parent import failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Legacy import failed.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,14 +38,12 @@ class BalanceCarryforwardController extends Controller
|
||||
public function waive(CarryforwardAdjustmentRequest $request, int $carryforward): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
return response()->json(['ok' => true, 'carryforward' => $this->service->waive($carryforward, (float) $data['amount'], $data['reason'] ?? null, optional($request->user())->id)]);
|
||||
}
|
||||
|
||||
public function adjust(CarryforwardAdjustmentRequest $request, int $carryforward): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
return response()->json(['ok' => true, 'carryforward' => $this->service->adjust($carryforward, (float) $data['amount'], $data['reason'] ?? null)]);
|
||||
}
|
||||
|
||||
@@ -57,12 +55,9 @@ class BalanceCarryforwardController extends Controller
|
||||
public function reportCsv(Request $request): StreamedResponse
|
||||
{
|
||||
$rows = $this->service->csvRows($this->service->report($request->query()));
|
||||
|
||||
return response()->streamDownload(function () use ($rows) {
|
||||
$out = fopen('php://output', 'w');
|
||||
foreach ($rows as $row) {
|
||||
fputcsv($out, $row);
|
||||
}
|
||||
foreach ($rows as $row) fputcsv($out, $row);
|
||||
fclose($out);
|
||||
}, 'carryforward_report_' . date('Ymd_His') . '.csv', ['Content-Type' => 'text/csv']);
|
||||
}
|
||||
|
||||
@@ -143,6 +143,9 @@ class ChargeController extends BaseApiController
|
||||
], $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -16,23 +16,14 @@ class EventChargeController extends Controller
|
||||
{
|
||||
$q = EventCharge::query();
|
||||
foreach (['parent_id','student_id','event_id','school_year','semester'] as $field) {
|
||||
if ($request->filled($field)) {
|
||||
$q->where($field, $request->query($field));
|
||||
}
|
||||
if ($request->filled($field)) $q->where($field, $request->query($field));
|
||||
}
|
||||
if ($request->filled('status')) {
|
||||
$status = $request->query('status');
|
||||
if (Schema::hasColumn('event_charges', 'status')) {
|
||||
$q->where('status', $status);
|
||||
} elseif ($status === 'paid') {
|
||||
$q->where('event_paid', 1);
|
||||
} elseif ($status === 'pending') {
|
||||
$q->where(function ($qq) {
|
||||
$qq->whereNull('event_paid')->orWhere('event_paid', 0);
|
||||
});
|
||||
if (Schema::hasColumn('event_charges', 'status')) $q->where('status', $status);
|
||||
elseif ($status === 'paid') $q->where('event_paid', 1);
|
||||
elseif ($status === 'pending') $q->where(function ($qq) { $qq->whereNull('event_paid')->orWhere('event_paid', 0); });
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true, 'event_charges' => $q->orderByDesc('id')->paginate((int) $request->query('per_page', 25))]);
|
||||
}
|
||||
|
||||
@@ -40,11 +31,8 @@ class EventChargeController extends Controller
|
||||
{
|
||||
$data = $this->normalizePayload($request->validated());
|
||||
$data['created_by'] = optional($request->user())->id;
|
||||
if (Schema::hasColumn('event_charges', 'status')) {
|
||||
$data['status'] = $data['status'] ?? 'draft';
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'status')) $data['status'] = $data['status'] ?? 'draft';
|
||||
$charge = EventCharge::query()->create($data);
|
||||
|
||||
return response()->json(['ok' => true, 'event_charge' => $charge], 201);
|
||||
}
|
||||
|
||||
@@ -57,7 +45,6 @@ class EventChargeController extends Controller
|
||||
{
|
||||
$charge = EventCharge::query()->findOrFail($eventCharge);
|
||||
$charge->fill($this->normalizePayload($request->validated()))->save();
|
||||
|
||||
return response()->json(['ok' => true, 'event_charge' => $charge->fresh()]);
|
||||
}
|
||||
|
||||
@@ -69,28 +56,18 @@ class EventChargeController extends Controller
|
||||
public function approve(int $eventCharge): JsonResponse
|
||||
{
|
||||
$charge = EventCharge::query()->findOrFail($eventCharge);
|
||||
if (Schema::hasColumn('event_charges', 'status')) {
|
||||
$charge->status = 'approved';
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'charged')) {
|
||||
$charge->charged = 1;
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'status')) $charge->status = 'approved';
|
||||
if (Schema::hasColumn('event_charges', 'charged')) $charge->charged = 1;
|
||||
$charge->save();
|
||||
|
||||
return response()->json(['ok' => true, 'event_charge' => $charge->fresh()]);
|
||||
}
|
||||
|
||||
public function void(int $eventCharge): JsonResponse
|
||||
{
|
||||
$charge = EventCharge::query()->findOrFail($eventCharge);
|
||||
if (Schema::hasColumn('event_charges', 'status')) {
|
||||
$charge->status = 'voided';
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'charged')) {
|
||||
$charge->charged = 0;
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'status')) $charge->status = 'voided';
|
||||
if (Schema::hasColumn('event_charges', 'charged')) $charge->charged = 0;
|
||||
$charge->save();
|
||||
|
||||
return response()->json(['ok' => true, 'event_charge' => $charge->fresh()]);
|
||||
}
|
||||
|
||||
@@ -100,27 +77,17 @@ class EventChargeController extends Controller
|
||||
$charge = EventCharge::query()->findOrFail($eventCharge);
|
||||
$invoiceId = (int) $request->input('invoice_id');
|
||||
abort_if(!DB::table('invoices')->where('id', $invoiceId)->exists(), 404, 'Invoice not found.');
|
||||
if (Schema::hasColumn('event_charges', 'invoice_id')) {
|
||||
$charge->invoice_id = $invoiceId;
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'status')) {
|
||||
$charge->status = 'invoiced';
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'charged')) {
|
||||
$charge->charged = 1;
|
||||
}
|
||||
if (Schema::hasColumn('event_charges', 'invoice_id')) $charge->invoice_id = $invoiceId;
|
||||
if (Schema::hasColumn('event_charges', 'status')) $charge->status = 'invoiced';
|
||||
if (Schema::hasColumn('event_charges', 'charged')) $charge->charged = 1;
|
||||
$charge->save();
|
||||
|
||||
return response()->json(['ok' => true, 'event_charge' => $charge->fresh(), 'warning' => Schema::hasColumn('event_charges','invoice_id') ? null : 'invoice_id column does not exist; charge marked as charged only.']);
|
||||
}
|
||||
|
||||
private function normalizePayload(array $data): array
|
||||
{
|
||||
if (isset($data['title']) && ! isset($data['event_name'])) {
|
||||
$data['event_name'] = $data['title'];
|
||||
}
|
||||
if (isset($data['title']) && !isset($data['event_name'])) $data['event_name'] = $data['title'];
|
||||
unset($data['title'], $data['invoice_id']);
|
||||
|
||||
return array_filter($data, fn($v) => $v !== null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,12 @@ class FinanceNotificationController extends Controller
|
||||
'recipient' => (string) ($p->parent_id ?? ''),
|
||||
'subject' => 'Payment receipt ' . $receipt,
|
||||
], optional($request->user())->id);
|
||||
|
||||
return response()->json(['ok' => true, 'receipt_number' => $receipt, 'notification_log' => $log]);
|
||||
}
|
||||
|
||||
public function sendRefundReceipt(Request $request, int $refund): JsonResponse
|
||||
{
|
||||
$log = $this->service->log(['refund_id' => $refund, 'notification_type' => 'refund_receipt', 'channel' => 'database', 'subject' => 'Refund receipt'], optional($request->user())->id);
|
||||
|
||||
return response()->json(['ok' => true, 'notification_log' => $log]);
|
||||
}
|
||||
|
||||
@@ -43,21 +41,18 @@ class FinanceNotificationController extends Controller
|
||||
$inv = DB::table('invoices')->where('id', $invoice)->first();
|
||||
abort_if(!$inv, 404, 'Invoice not found.');
|
||||
$log = $this->service->log(['parent_id' => $inv->parent_id ?? null, 'invoice_id' => $invoice, 'notification_type' => 'statement_available', 'channel' => 'database', 'subject' => 'Statement available'], optional($request->user())->id);
|
||||
|
||||
return response()->json(['ok' => true, 'notification_log' => $log]);
|
||||
}
|
||||
|
||||
public function sendOverdueReminder(Request $request, int $parent): JsonResponse
|
||||
{
|
||||
$log = $this->service->log(['parent_id' => $parent, 'notification_type' => 'overdue_balance_reminder', 'channel' => 'database', 'subject' => 'Overdue balance reminder'], optional($request->user())->id);
|
||||
|
||||
return response()->json(['ok' => true, 'notification_log' => $log]);
|
||||
}
|
||||
|
||||
public function sendInstallmentReminder(Request $request, int $installment): JsonResponse
|
||||
{
|
||||
$log = $this->service->log(['installment_id' => $installment, 'notification_type' => 'installment_reminder', 'channel' => 'database', 'subject' => 'Installment reminder'], optional($request->user())->id);
|
||||
|
||||
return response()->json(['ok' => true, 'notification_log' => $log]);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ namespace App\Http\Controllers\Api\Finance;
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Finance\FinancialReportRequest;
|
||||
use App\Http\Requests\Finance\FinancialSummaryRequest;
|
||||
use App\Http\Requests\Finance\FinancialUnpaidParentsRequest;
|
||||
use App\Http\Requests\Finance\FollowUpNoteRequest;
|
||||
use App\Http\Requests\Finance\ParentPaymentFollowUpRequest;
|
||||
use App\Http\Requests\Finance\StakeholderFinancialAnalysisRequest;
|
||||
use App\Http\Requests\Finance\FinancialUnpaidParentsRequest;
|
||||
use App\Http\Requests\Finance\ParentPaymentFollowUpRequest;
|
||||
use App\Http\Requests\Finance\FollowUpNoteRequest;
|
||||
use App\Http\Resources\Finance\FinancialReportResource;
|
||||
use App\Http\Resources\Finance\FinancialSummaryResource;
|
||||
use App\Http\Resources\Finance\FinancialUnpaidParentResource;
|
||||
@@ -16,9 +16,9 @@ use App\Services\Finance\FinancialPdfReportService;
|
||||
use App\Services\Finance\FinancialReportService;
|
||||
use App\Services\Finance\FinancialSchoolYearService;
|
||||
use App\Services\Finance\FinancialSummaryService;
|
||||
use App\Services\Finance\StakeholderFinancialAnalysisService;
|
||||
use App\Services\Finance\FinancialUnpaidParentsService;
|
||||
use App\Services\Finance\ParentPaymentFollowUpService;
|
||||
use App\Services\Finance\StakeholderFinancialAnalysisService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
@@ -82,6 +82,9 @@ class FinancialController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function parentPaymentFollowups(ParentPaymentFollowUpRequest $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
@@ -115,21 +118,18 @@ class FinancialController extends BaseApiController
|
||||
public function markParentContacted(FollowUpNoteRequest $request, int $parent): JsonResponse
|
||||
{
|
||||
$payload = array_merge($request->validated(), ['status' => $request->input('status', 'contacted')]);
|
||||
|
||||
return response()->json(['ok' => true, 'note' => $this->parentPaymentFollowUpService->storeNote($parent, $payload, optional($request->user())->id)], 201);
|
||||
}
|
||||
|
||||
public function storePromiseToPay(FollowUpNoteRequest $request, int $parent): JsonResponse
|
||||
{
|
||||
$payload = array_merge($request->validated(), ['status' => 'promise_to_pay']);
|
||||
|
||||
return response()->json(['ok' => true, 'note' => $this->parentPaymentFollowUpService->storeNote($parent, $payload, optional($request->user())->id)], 201);
|
||||
}
|
||||
|
||||
public function resolveParentFollowUp(FollowUpNoteRequest $request, int $parent): JsonResponse
|
||||
{
|
||||
$payload = array_merge($request->validated(), ['status' => 'resolved']);
|
||||
|
||||
return response()->json(['ok' => true, 'note' => $this->parentPaymentFollowUpService->storeNote($parent, $payload, optional($request->user())->id)], 201);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,52 +13,17 @@ class InstallmentPlanController extends Controller
|
||||
{
|
||||
public function __construct(private InstallmentPlanService $service) {}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'plans' => $this->service->list($request->query())]);
|
||||
}
|
||||
|
||||
public function store(InstallmentPlanRequest $request, int $invoice): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'plan' => $this->service->createForInvoice($invoice, $request->validated(), optional($request->user())->id)], 201);
|
||||
}
|
||||
|
||||
public function show(int $plan): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'plan' => $this->service->show($plan)]);
|
||||
}
|
||||
|
||||
public function activate(Request $request, int $plan): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'plan' => $this->service->activate($plan, optional($request->user())->id)]);
|
||||
}
|
||||
|
||||
public function cancel(int $plan): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'plan' => $this->service->cancel($plan)]);
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse { return response()->json(['ok' => true, 'plans' => $this->service->list($request->query())]); }
|
||||
public function store(InstallmentPlanRequest $request, int $invoice): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->createForInvoice($invoice, $request->validated(), optional($request->user())->id)], 201); }
|
||||
public function show(int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->show($plan)]); }
|
||||
public function activate(Request $request, int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->activate($plan, optional($request->user())->id)]); }
|
||||
public function cancel(int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->cancel($plan)]); }
|
||||
public function restructure(InstallmentPlanRequest $request, int $plan): JsonResponse
|
||||
{
|
||||
$old = $this->service->cancel($plan);
|
||||
|
||||
return response()->json(['ok' => true, 'old_plan' => $old, 'message' => 'Old plan cancelled. Create a replacement plan against the invoice to preserve audit history.']);
|
||||
}
|
||||
|
||||
public function allocatePayment(PaymentAllocationRequest $request, int $payment): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'result' => $this->service->allocatePayment($payment, $request->validated())]);
|
||||
}
|
||||
|
||||
public function due(): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'installments' => $this->service->due(false)]);
|
||||
}
|
||||
|
||||
public function overdue(): JsonResponse
|
||||
{
|
||||
$this->service->markOverdue();
|
||||
|
||||
return response()->json(['ok' => true, 'installments' => $this->service->due(true)]);
|
||||
}
|
||||
public function allocatePayment(PaymentAllocationRequest $request, int $payment): JsonResponse { return response()->json(['ok' => true, 'result' => $this->service->allocatePayment($payment, $request->validated())]); }
|
||||
public function due(): JsonResponse { return response()->json(['ok' => true, 'installments' => $this->service->due(false)]); }
|
||||
public function overdue(): JsonResponse { $this->service->markOverdue(); return response()->json(['ok' => true, 'installments' => $this->service->due(true)]); }
|
||||
}
|
||||
|
||||
@@ -154,6 +154,9 @@ class InvoiceController extends BaseApiController
|
||||
}, 'invoice_' . $invoiceId . '.pdf', ['Content-Type' => 'application/pdf']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -69,6 +69,9 @@ class PaymentEventChargesController extends BaseApiController
|
||||
return response()->json(['ok' => true, 'students' => $students]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Services\Payments\PaymentManualService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PaymentManualController extends BaseApiController
|
||||
{
|
||||
@@ -70,6 +71,7 @@ class PaymentManualController extends BaseApiController
|
||||
|
||||
$payload = $request->validated();
|
||||
|
||||
try {
|
||||
$result = $this->service->recordPayment(
|
||||
$invoiceId,
|
||||
(float) $payload['amount'],
|
||||
@@ -82,6 +84,12 @@ class PaymentManualController extends BaseApiController
|
||||
$payload['semester'] ?? null,
|
||||
$guard
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Manual payment record failed: ' . $e->getMessage());
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to record payment.'], 400);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $result);
|
||||
}
|
||||
@@ -95,6 +103,7 @@ class PaymentManualController extends BaseApiController
|
||||
|
||||
$payload = $request->validated();
|
||||
|
||||
try {
|
||||
$this->service->editPayment(
|
||||
$paymentId,
|
||||
(float) $payload['paid_amount'],
|
||||
@@ -103,6 +112,12 @@ class PaymentManualController extends BaseApiController
|
||||
$request->file('payment_file'),
|
||||
$guard
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Manual payment edit failed: ' . $e->getMessage());
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to update payment.'], 400);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
@@ -110,10 +125,12 @@ class PaymentManualController extends BaseApiController
|
||||
public function file(Request $request, string $filename)
|
||||
{
|
||||
$mode = (string) ($request->query('mode') ?? 'download');
|
||||
|
||||
return $this->service->serveCheckFile($filename, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -71,7 +71,6 @@ class RefundController extends BaseApiController
|
||||
$result = $this->requestService->requestRefund($payload, $guard);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Refund request failed.', ['error' => $e->getMessage()]);
|
||||
|
||||
return response()->json(['ok' => false, 'message' => 'Failed to submit refund request.'], 500);
|
||||
}
|
||||
|
||||
@@ -213,6 +212,9 @@ class RefundController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -93,7 +93,6 @@ class ReimbursementController extends BaseApiController
|
||||
} catch (RuntimeException $e) {
|
||||
$message = $e->getMessage();
|
||||
$status = str_contains($message, 'not found') ? 404 : (str_contains($message, 'already') ? 409 : 422);
|
||||
|
||||
return response()->json(['ok' => false, 'message' => $message], $status);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to mark donation right now.'], 500);
|
||||
@@ -185,7 +184,6 @@ class ReimbursementController extends BaseApiController
|
||||
} catch (RuntimeException $e) {
|
||||
$message = $e->getMessage();
|
||||
$status = str_contains($message, 'check file') ? 409 : 404;
|
||||
|
||||
return response()->json(['ok' => false, 'message' => $message], $status);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to lock batch right now.'], 500);
|
||||
@@ -480,6 +478,9 @@ class ReimbursementController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -29,6 +29,9 @@ class InfoIconController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
namespace App\Http\Controllers\Api\Grading;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Grading\BelowSixtyEmailRequest;
|
||||
use App\Http\Requests\Grading\AllDecisionsRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyDecisionDetailsRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyDecisionListRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyDecisionSaveRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyDecisionSendRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyEmailRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyListRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyMeetingRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyMeetingSaveRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtySendRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyStatusRequest;
|
||||
use App\Http\Requests\Grading\BelowSixtyListRequest;
|
||||
use App\Http\Requests\Grading\GenerateAllDecisionsRequest;
|
||||
use App\Http\Requests\Grading\GradingLockAllRequest;
|
||||
use App\Http\Requests\Grading\GradingLockRequest;
|
||||
@@ -23,8 +23,8 @@ use App\Http\Requests\Grading\GradingScoreShowRequest;
|
||||
use App\Http\Requests\Grading\GradingScoreUpdateRequest;
|
||||
use App\Http\Requests\Grading\PlacementBatchRequest;
|
||||
use App\Http\Requests\Grading\PlacementBatchUpdateRequest;
|
||||
use App\Http\Requests\Grading\PlacementLevelRequest;
|
||||
use App\Http\Requests\Grading\PlacementLevelsRequest;
|
||||
use App\Http\Requests\Grading\PlacementLevelRequest;
|
||||
use App\Http\Requests\Grading\PlacementRequest;
|
||||
use App\Http\Resources\Grading\BelowSixtyStudentResource;
|
||||
use App\Http\Resources\Grading\GradingScoreResource;
|
||||
@@ -419,6 +419,9 @@ class GradingController extends BaseApiController
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api\Incidents;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Incidents\IncidentCancelRequest;
|
||||
use App\Http\Requests\Incidents\IncidentCloseRequest;
|
||||
use App\Http\Requests\Incidents\IncidentListRequest;
|
||||
use App\Http\Requests\Incidents\IncidentStateRequest;
|
||||
use App\Http\Resources\Incidents\IncidentAnalysisStudentResource;
|
||||
@@ -208,6 +209,9 @@ class IncidentController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -128,7 +128,6 @@ class InventoryController extends BaseApiController
|
||||
public function summary(string $type): JsonResponse
|
||||
{
|
||||
$payload = $this->summary->summary($type, request()->query('school_year'));
|
||||
|
||||
return $this->success($payload);
|
||||
}
|
||||
|
||||
@@ -138,7 +137,6 @@ class InventoryController extends BaseApiController
|
||||
request()->query('school_year'),
|
||||
request()->query('type')
|
||||
);
|
||||
|
||||
return $this->success($payload);
|
||||
}
|
||||
|
||||
@@ -174,7 +172,6 @@ class InventoryController extends BaseApiController
|
||||
$result = $this->distribution->distribute($actor, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Inventory distribution failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to distribute inventory.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -185,6 +182,9 @@ class InventoryController extends BaseApiController
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -73,6 +73,9 @@ class InventoryMovementController extends BaseApiController
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -105,7 +105,6 @@ class MessagesController extends BaseApiController
|
||||
$message = $this->commandService->create($guard, $request->validated(), $request->file('attachment'));
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Message send failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
@@ -161,7 +160,6 @@ class MessagesController extends BaseApiController
|
||||
$updated = $this->commandService->update($message, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Message update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to update message.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -183,7 +181,6 @@ class MessagesController extends BaseApiController
|
||||
$trashed = $this->commandService->trash($message);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Message delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to delete message.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -223,6 +220,9 @@ class MessagesController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -118,7 +118,6 @@ class WhatsappController extends BaseApiController
|
||||
$result = $this->inviteService->send($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('WhatsApp invite send failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Invite processing failed.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -142,7 +141,6 @@ class WhatsappController extends BaseApiController
|
||||
$result = $this->membershipService->updateMembership($request->validated(), $userId);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('WhatsApp membership update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to save membership.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -160,6 +158,9 @@ class WhatsappController extends BaseApiController
|
||||
], 'Membership saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -82,7 +82,6 @@ class NotificationController extends BaseApiController
|
||||
$result = $this->sendService->send($payload, $guard);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Notification send failed.', ['error' => $e->getMessage()]);
|
||||
|
||||
return response()->json(['ok' => false, 'message' => 'Failed to send notification.'], 500);
|
||||
}
|
||||
|
||||
@@ -168,6 +167,9 @@ class NotificationController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace App\Http\Controllers\Api\Parents;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportCheckRequest;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportListRequest;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportSubmitRequest;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportListRequest;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportCheckRequest;
|
||||
use App\Http\Requests\Parents\ParentAttendanceReportUpdateRequest;
|
||||
use App\Http\Resources\Parents\ParentAttendanceReportResource;
|
||||
use App\Services\Parents\ParentAttendanceReportService;
|
||||
@@ -116,6 +116,9 @@ class ParentAttendanceReportController extends BaseApiController
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function parentIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$parentId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -4,18 +4,18 @@ namespace App\Http\Controllers\Api\Parents;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Parents\ParentAttendanceRequest;
|
||||
use App\Http\Requests\Parents\ParentEmergencyContactRequest;
|
||||
use App\Http\Requests\Parents\ParentEnrollmentActionRequest;
|
||||
use App\Http\Requests\Parents\ParentEnrollmentRequest;
|
||||
use App\Http\Requests\Parents\ParentEmergencyContactRequest;
|
||||
use App\Http\Requests\Parents\ParentEventParticipationRequest;
|
||||
use App\Http\Requests\Parents\ParentInvoiceRequest;
|
||||
use App\Http\Requests\Parents\ParentProfileUpdateRequest;
|
||||
use App\Http\Requests\Parents\ParentRegistrationRequest;
|
||||
use App\Http\Requests\Parents\ParentStudentUpdateRequest;
|
||||
use App\Http\Resources\Invoices\InvoiceResource;
|
||||
use App\Http\Resources\Parents\ParentAttendanceResource;
|
||||
use App\Http\Resources\Parents\ParentEmergencyContactResource;
|
||||
use App\Http\Resources\Parents\ParentStudentResource;
|
||||
use App\Http\Resources\Invoices\InvoiceResource;
|
||||
use App\Services\Parents\ParentAttendanceService;
|
||||
use App\Services\Parents\ParentEmergencyContactService;
|
||||
use App\Services\Parents\ParentEnrollmentService;
|
||||
|
||||
@@ -154,7 +154,6 @@ class ParentPromotionController extends BaseApiController
|
||||
if (!$owns) {
|
||||
return response()->json(['ok' => false, 'message' => 'You are not authorised to view this promotion record.'], Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
@@ -169,7 +168,6 @@ class ParentPromotionController extends BaseApiController
|
||||
if ($parentId <= 0) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
return $parentId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ use App\Models\User;
|
||||
use App\Services\PrintRequests\PrintRequestsPortalService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
@@ -60,7 +59,7 @@ class PrintRequestsController extends BaseApiController
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
|
||||
/** @var UploadedFile $file */
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
$file = $request->file('file');
|
||||
$model = $this->portal->storeTeacherUpload($validator->validated(), $file, $uid);
|
||||
|
||||
|
||||
@@ -102,7 +102,6 @@ class ReportCardsController extends BaseApiController
|
||||
$result = $this->service->generateSingleReport($studentId, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Report card PDF generation failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to generate report card.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -126,7 +125,6 @@ class ReportCardsController extends BaseApiController
|
||||
$result = $this->service->generateClassReport($classSectionId, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Class report card PDF generation failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to generate class report cards.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -150,7 +148,6 @@ class ReportCardsController extends BaseApiController
|
||||
if ($value !== '') {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return trim((string) (Configuration::getConfig('school_year') ?? ''));
|
||||
}
|
||||
|
||||
@@ -160,7 +157,6 @@ class ReportCardsController extends BaseApiController
|
||||
if ($value !== '') {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return trim((string) (Configuration::getConfig('semester') ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,9 @@ class SlipPrinterController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -65,7 +65,6 @@ class StickersController extends BaseApiController
|
||||
$result = $this->printService->generate($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Sticker print failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to generate stickers.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ class RolePermissionController extends BaseApiController
|
||||
$role = $this->roleCrudService->create($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role store failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to create role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -90,7 +89,6 @@ class RolePermissionController extends BaseApiController
|
||||
$role = $this->roleCrudService->update($role, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -110,7 +108,6 @@ class RolePermissionController extends BaseApiController
|
||||
$this->roleCrudService->delete($role);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to delete role.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -142,7 +139,6 @@ class RolePermissionController extends BaseApiController
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Assign roles failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update roles.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -182,7 +178,6 @@ class RolePermissionController extends BaseApiController
|
||||
$permission = $this->permissionCrudService->create($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission store failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to create permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -202,7 +197,6 @@ class RolePermissionController extends BaseApiController
|
||||
$permission = $this->permissionCrudService->update($permission, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -222,7 +216,6 @@ class RolePermissionController extends BaseApiController
|
||||
$this->permissionCrudService->delete($permission);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Permission delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to delete permission.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -244,7 +237,6 @@ class RolePermissionController extends BaseApiController
|
||||
$this->permissionService->saveRolePermissions($roleId, $request->validated()['permissions'] ?? []);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Role permissions update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update role permissions.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Http\Requests\Roles\RoleSwitchRequest;
|
||||
use App\Services\Roles\RoleSwitchService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RoleSwitcherController extends BaseApiController
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@ use Illuminate\Support\Facades\Schema;
|
||||
class ScannerController extends BaseApiController
|
||||
{
|
||||
private const LATE_CUTOFF_CONFIG_KEY = 'attendance_late_cutoff_time';
|
||||
|
||||
private const DEFAULT_LATE_CUTOFF = '10:00 AM';
|
||||
|
||||
public function process(Request $request): JsonResponse
|
||||
@@ -42,7 +41,6 @@ class ScannerController extends BaseApiController
|
||||
|
||||
if ($badgeCode === '') {
|
||||
$this->logScan($badgeCode, null, null, $action, 'rejected', $operatorId, $stationId, 'Badge code is required.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Badge code is required.'), 400);
|
||||
}
|
||||
|
||||
@@ -61,7 +59,6 @@ class ScannerController extends BaseApiController
|
||||
}
|
||||
|
||||
$this->logScan($badgeCode, null, null, $action, 'not_found', $operatorId, $stationId, 'Badge not found.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Badge not found.'), 404);
|
||||
}
|
||||
|
||||
@@ -79,7 +76,6 @@ class ScannerController extends BaseApiController
|
||||
$assignment = $this->studentAssignment((int) $student->id, $term['semester'], $term['school_year']);
|
||||
if (!$assignment) {
|
||||
$this->logScan($badgeCode, 'student', (int) $student->id, $action, 'rejected', $operatorId, $stationId, 'Student has no class assignment for current term.', $scannedAt);
|
||||
|
||||
return response()->json($this->failure('Student has no class assignment for current term.'), 409);
|
||||
}
|
||||
|
||||
@@ -335,7 +331,6 @@ class ScannerController extends BaseApiController
|
||||
|
||||
if (!$record) {
|
||||
$this->addAttendanceRecord($classSectionId, $studentId, $schoolId, $newStatus, $semester, $schoolYear, $operatorId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -388,7 +383,6 @@ class ScannerController extends BaseApiController
|
||||
'updated_at' => utc_now(),
|
||||
]);
|
||||
$record->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -778,7 +772,6 @@ class ScannerController extends BaseApiController
|
||||
}
|
||||
|
||||
Log::warning(self::LATE_CUTOFF_CONFIG_KEY . ' has invalid value "' . $configured . '"; using ' . self::DEFAULT_LATE_CUTOFF);
|
||||
|
||||
return $schoolNow->setTime(10, 0, 0);
|
||||
}
|
||||
|
||||
@@ -787,7 +780,6 @@ class ScannerController extends BaseApiController
|
||||
$timezone = new \DateTimeZone('America/New_York');
|
||||
try {
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
|
||||
return (new \DateTimeImmutable($scannedAt, $utc))->setTimezone($timezone);
|
||||
} catch (\Throwable) {
|
||||
return new \DateTimeImmutable('now', $timezone);
|
||||
|
||||
@@ -135,6 +135,9 @@ class FinalController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -158,6 +158,9 @@ class HomeworkController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -135,6 +135,9 @@ class MidtermController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -138,6 +138,9 @@ class ParticipationController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -159,6 +159,9 @@ class ProjectController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -158,6 +158,9 @@ class QuizController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -119,6 +119,9 @@ class ScoreCommentController extends BaseApiController
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -81,6 +81,9 @@ class ScoreController extends BaseApiController
|
||||
return response()->json(['ok' => true] + $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (request()->user()?->id ?? auth()->id() ?? 0);
|
||||
|
||||
@@ -73,7 +73,6 @@ class EventController extends BaseApiController
|
||||
$result = $this->managementService->create($payload, $request->file('flyer'), $guard);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Event creation failed.', ['error' => $e->getMessage()]);
|
||||
|
||||
return response()->json(['ok' => false, 'message' => 'Failed to create event.'], 500);
|
||||
}
|
||||
|
||||
@@ -177,6 +176,9 @@ class EventController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -83,7 +83,6 @@ class PreferencesController extends BaseApiController
|
||||
$saved = $this->commandService->upsert($guard, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Preferences save failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to save preferences.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -105,7 +104,6 @@ class PreferencesController extends BaseApiController
|
||||
$saved = $this->commandService->upsert($userId, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Preferences update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to save preferences.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -129,7 +127,6 @@ class PreferencesController extends BaseApiController
|
||||
$deleted = $this->commandService->delete($row);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Preferences delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to delete preferences.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -140,6 +137,9 @@ class PreferencesController extends BaseApiController
|
||||
return $this->success(null, 'Preferences deleted.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -117,7 +117,6 @@ class SchoolCalendarController extends BaseApiController
|
||||
$result = $this->mutationService->create($payload, $targets);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('SchoolCalendar store failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to save event.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -141,7 +140,6 @@ class SchoolCalendarController extends BaseApiController
|
||||
$result = $this->mutationService->update($event, $payload, $targets);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('SchoolCalendar update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to update event.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -162,7 +160,6 @@ class SchoolCalendarController extends BaseApiController
|
||||
$this->mutationService->delete($event);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('SchoolCalendar delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Failed to delete event.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -178,6 +175,9 @@ class SchoolCalendarController extends BaseApiController
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -41,7 +41,6 @@ class SettingsController extends BaseApiController
|
||||
$updated = $this->settingsService->update($request->validated(), $guard);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Settings update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to update settings.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -50,6 +49,9 @@ class SettingsController extends BaseApiController
|
||||
], 'Settings updated.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -9,7 +9,6 @@ use App\Http\Requests\Staff\StaffUpdateRequest;
|
||||
use App\Http\Resources\Staff\StaffCollection;
|
||||
use App\Http\Resources\Staff\StaffResource;
|
||||
use App\Models\Staff;
|
||||
use App\Models\User;
|
||||
use App\Services\Staff\StaffCommandService;
|
||||
use App\Services\Staff\StaffQueryService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -53,7 +52,7 @@ class StaffController extends BaseApiController
|
||||
}
|
||||
|
||||
$this->authorize('view', $staff);
|
||||
$staff->school_id = User::getSchoolIdByUserId((int) ($staff->user_id ?? 0));
|
||||
$staff->school_id = \App\Models\User::getSchoolIdByUserId((int) ($staff->user_id ?? 0));
|
||||
|
||||
return $this->success([
|
||||
'staff' => new StaffResource($staff),
|
||||
@@ -68,7 +67,6 @@ class StaffController extends BaseApiController
|
||||
$staff = $this->commandService->create($request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Staff create failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
@@ -90,7 +88,6 @@ class StaffController extends BaseApiController
|
||||
$updated = $this->commandService->update($staff, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Staff update failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to update staff.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -112,7 +109,6 @@ class StaffController extends BaseApiController
|
||||
$deleted = $this->commandService->delete($staff);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Staff delete failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to delete staff.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +142,9 @@ class TeacherController extends BaseApiController
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Models\Stats;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class StatsController extends BaseApiController
|
||||
@@ -11,12 +13,14 @@ class StatsController extends BaseApiController
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
if (! Schema::hasTable('stats')) {
|
||||
return $this->success([], 'Statistics retrieved successfully');
|
||||
}
|
||||
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
return $this->success($stats, 'Statistics retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Stats retrieval error: '.$e->getMessage());
|
||||
|
||||
return $this->respondError('Failed to retrieve statistics', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use App\Http\Resources\Students\StudentClassSectionResource;
|
||||
use App\Http\Resources\Students\StudentRemovedResource;
|
||||
use App\Http\Resources\Students\StudentScoreCardRowResource;
|
||||
use App\Models\AttendanceRecord;
|
||||
use App\Models\ClassSection;
|
||||
use App\Models\EmergencyContact;
|
||||
use App\Models\Incident;
|
||||
use App\Models\SemesterScore;
|
||||
@@ -67,7 +68,7 @@ class StudentController extends BaseApiController
|
||||
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
||||
$validator = Validator::make($data, [
|
||||
'school_year' => ['nullable', 'string', 'max:50'],
|
||||
'parent_id' => ['nullable', 'integer', 'min:1'],
|
||||
'parent_id' => ['required', 'integer', 'min:1'],
|
||||
'parent_ids' => ['nullable', 'array'],
|
||||
'parent_ids.*' => ['integer', 'min:1'],
|
||||
]);
|
||||
@@ -192,17 +193,17 @@ class StudentController extends BaseApiController
|
||||
'firstname' => ['required', 'string', 'max:150'],
|
||||
'lastname' => ['required', 'string', 'max:150'],
|
||||
'dob' => ['nullable', 'date'],
|
||||
'age' => ['nullable', 'integer', 'min:0'],
|
||||
'gender' => ['nullable', 'string', 'max:20'],
|
||||
'age' => ['required', 'integer', 'min:0'],
|
||||
'gender' => ['required', 'string', 'max:20'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
'registration_grade' => ['nullable', 'string', 'max:50'],
|
||||
'is_new' => ['nullable', 'boolean'],
|
||||
'photo_consent' => ['nullable', 'boolean'],
|
||||
'parent_id' => ['nullable', 'integer', 'min:1'],
|
||||
'photo_consent' => ['required', 'boolean'],
|
||||
'parent_id' => ['required', 'integer', 'min:1'],
|
||||
'registration_date' => ['nullable', 'date'],
|
||||
'tuition_paid' => ['nullable', 'boolean'],
|
||||
'semester' => ['nullable', 'string', 'max:50'],
|
||||
'year_of_registration' => ['nullable', 'integer', 'min:1900'],
|
||||
'year_of_registration' => ['required', 'integer', 'min:1900'],
|
||||
'school_year' => ['required', 'string', 'max:50'],
|
||||
'medical_conditions' => ['nullable', 'string'],
|
||||
'allergies' => ['nullable', 'string'],
|
||||
@@ -229,7 +230,26 @@ class StudentController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $validator->validated();
|
||||
$student = Student::query()->create($payload);
|
||||
$studentPayload = collect($payload)->only([
|
||||
'school_id',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'dob',
|
||||
'age',
|
||||
'gender',
|
||||
'is_active',
|
||||
'registration_grade',
|
||||
'is_new',
|
||||
'photo_consent',
|
||||
'parent_id',
|
||||
'registration_date',
|
||||
'tuition_paid',
|
||||
'semester',
|
||||
'year_of_registration',
|
||||
'school_year',
|
||||
])->all();
|
||||
|
||||
$student = Student::query()->create($studentPayload);
|
||||
|
||||
if (empty($student->school_id)) {
|
||||
$student->school_id = $this->generateSchoolId($student->id);
|
||||
@@ -795,7 +815,6 @@ class StudentController extends BaseApiController
|
||||
private function generateSchoolId(int $studentId): string
|
||||
{
|
||||
$year = (int) date('y');
|
||||
|
||||
return 'STU' . $year . str_pad((string) $studentId, 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ class SupportController extends BaseApiController
|
||||
$result = $this->supportService->create((int) $user->id, $payload);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Support request failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to submit support request.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@@ -87,6 +86,9 @@ class SupportController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|JsonResponse
|
||||
*/
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -15,7 +15,8 @@ class DashboardRedirectController extends Controller
|
||||
public function __construct(
|
||||
private DashboardRouteService $service,
|
||||
private ApplicationUrlService $urls,
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function dashboard(): RedirectResponse
|
||||
{
|
||||
|
||||
@@ -8,8 +8,8 @@ use App\Http\Requests\System\NavItemStoreRequest;
|
||||
use App\Http\Resources\System\NavBuilderDataResource;
|
||||
use App\Http\Resources\System\NavItemResource;
|
||||
use App\Models\NavItem;
|
||||
use App\Services\Navigation\NavbarService;
|
||||
use App\Services\Navigation\NavBuilderService;
|
||||
use App\Services\Navigation\NavbarService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -82,7 +82,6 @@ class NavBuilderController extends BaseApiController
|
||||
$this->builderService->reorder($request->validated()['orders']);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Nav reorder failed: ' . $e->getMessage());
|
||||
|
||||
return $this->error('Unable to reorder items.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\System;
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Models\Stats;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class StatsController extends BaseApiController
|
||||
@@ -12,12 +13,14 @@ class StatsController extends BaseApiController
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
if (! Schema::hasTable('stats')) {
|
||||
return $this->success([], 'Statistics retrieved successfully');
|
||||
}
|
||||
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
return $this->success($stats, 'Statistics retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Stats retrieval error: '.$e->getMessage());
|
||||
|
||||
return $this->respondError('Failed to retrieve statistics', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user