Files
alrahma_sunday_school_api/app/Http/Controllers/Web/SchoolYearAdminPageController.php
T
2026-06-08 23:30:22 -04:00

149 lines
5.7 KiB
PHP

<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Services\SchoolYears\SchoolYearClosureService;
use App\Services\SchoolYears\SchoolYearResolver;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
class SchoolYearAdminPageController extends Controller
{
public function __construct(
private SchoolYearClosureService $service,
private SchoolYearResolver $resolver
) {}
public function show(Request $request): View
{
$years = $this->service->list();
$selectedId = (int) ($request->query('year') ?? 0);
$activeYear = collect($years)->firstWhere('is_current', true);
$defaultNext = $activeYear
? ($this->resolver->suggestNextName((string) $activeYear['name']) ?? '')
: '';
[$defaultStart, $defaultEnd] = $defaultNext !== ''
? $this->resolver->inferDatesFromName($defaultNext)
: ['', ''];
return view('admin.school-years', [
'pageConfig' => [
'jwt' => JWTAuth::fromUser($request->user()),
'selected_year_id' => $selectedId,
'docs_url' => url('/docs'),
'default_draft' => [
'name' => $defaultNext,
'start_date' => $defaultStart,
'end_date' => $defaultEnd,
],
'api' => [
'index' => url('/api/v1/school-years'),
'store' => url('/api/v1/school-years'),
'update' => url('/api/v1/school-years/__ID__'),
'summary' => url('/api/v1/school-years/__ID__/summary'),
'validate_close' => url('/api/v1/school-years/__ID__/validate-close'),
'preview_close' => url('/api/v1/school-years/__ID__/preview-close'),
'close' => url('/api/v1/school-years/__ID__/close'),
'reopen' => url('/api/v1/school-years/__ID__/reopen'),
'parent_balances' => url('/api/v1/school-years/__ID__/parent-balances'),
'promotion_preview' => url('/api/v1/school-years/__ID__/promotion-preview'),
],
],
]);
}
public function store(Request $request): RedirectResponse
{
$payload = $request->validate([
'name' => ['required', 'string', 'max:50'],
'start_date' => ['required', 'date'],
'end_date' => ['required', 'date', 'after:start_date'],
]);
try {
$year = $this->service->createYear($payload, optional($request->user())->id);
} catch (ValidationException $e) {
throw $e;
}
return redirect()
->route('admin.school-years', ['year' => $year['id']])
->with('status', sprintf('Draft school year %s created.', $year['name']));
}
public function update(Request $request, int $schoolYear): RedirectResponse
{
$payload = $request->validate([
'name' => ['required', 'string', 'max:50'],
'start_date' => ['required', 'date'],
'end_date' => ['required', 'date', 'after:start_date'],
]);
$updated = $this->service->updateYear($schoolYear, $payload, optional($request->user())->id);
return redirect()
->route('admin.school-years', ['year' => $updated['id']])
->with('status', sprintf('School year %s updated.', $updated['name']));
}
public function validateClose(Request $request, int $schoolYear): JsonResponse
{
return response()->json([
'ok' => true,
'validation' => $this->service->validateClose($schoolYear, $this->validatedClosePayload($request)),
]);
}
public function previewClose(Request $request, int $schoolYear): JsonResponse
{
return response()->json([
'ok' => true,
'data' => $this->service->previewClose($schoolYear, $this->validatedClosePayload($request)),
]);
}
public function close(Request $request, int $schoolYear): RedirectResponse
{
$payload = $this->validatedClosePayload($request);
$payload['confirmation'] = (string) $request->validate([
'confirmation' => ['required', 'string', 'max:80'],
])['confirmation'];
$result = $this->service->close($schoolYear, $payload, optional($request->user())->id);
return redirect()
->route('admin.school-years', ['year' => $result['new_school_year']['id']])
->with('status', sprintf(
'Closed %s and opened %s.',
$result['closed_school_year']['name'],
$result['new_school_year']['name']
));
}
public function reopen(Request $request, int $schoolYear): RedirectResponse
{
$year = $this->service->reopen($schoolYear, optional($request->user())->id);
return redirect()
->route('admin.school-years', ['year' => $year['id']])
->with('status', sprintf('School year %s is now active.', $year['name']));
}
private function validatedClosePayload(Request $request): array
{
return $request->validate([
'new_school_year' => ['required', 'array'],
'new_school_year.name' => ['required', 'string', 'max:50'],
'new_school_year.start_date' => ['required', 'date'],
'new_school_year.end_date' => ['required', 'date', 'after:new_school_year.start_date'],
'transfer_unpaid_balances' => ['nullable', 'boolean'],
]);
}
}