add school year model
This commit is contained in:
@@ -16,9 +16,9 @@ class AdministratorTeacherSubmissionController extends Controller
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json($this->service->report());
|
||||
return response()->json($this->service->report($request->query()));
|
||||
}
|
||||
|
||||
public function notify(Request $request): JsonResponse
|
||||
|
||||
@@ -23,6 +23,8 @@ class EmailExtractorController extends BaseApiController
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'users' => $emails['users'] ?? [],
|
||||
'parents' => $emails['parents'] ?? [],
|
||||
'emails' => new EmailExtractorEmailsResource($emails),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\SchoolYears;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\SchoolYears\CloseSchoolYearRequest;
|
||||
use App\Http\Requests\SchoolYears\PreviewCloseSchoolYearRequest;
|
||||
use App\Http\Requests\SchoolYears\SaveSchoolYearRequest;
|
||||
use App\Services\SchoolYears\SchoolYearClosureService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SchoolYearController extends BaseApiController
|
||||
{
|
||||
public function __construct(private SchoolYearClosureService $service)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'data' => $this->service->list()]);
|
||||
}
|
||||
|
||||
public function store(SaveSchoolYearRequest $request): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->createYear($request->validated(), $this->getCurrentUserId()),
|
||||
], Response::HTTP_CREATED);
|
||||
}
|
||||
|
||||
public function update(SaveSchoolYearRequest $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->updateYear($schoolYear, $request->validated(), $this->getCurrentUserId()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function summary(int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json(['ok' => true, 'data' => $this->service->summary($schoolYear)]);
|
||||
}
|
||||
|
||||
public function validateClose(PreviewCloseSchoolYearRequest $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'validation' => $this->service->validateClose($schoolYear, $request->validated()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function previewClose(PreviewCloseSchoolYearRequest $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->previewClose($schoolYear, $request->validated()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function close(CloseSchoolYearRequest $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
try {
|
||||
$result = $this->service->close($schoolYear, $request->validated(), $this->getCurrentUserId());
|
||||
} catch (ValidationException $e) {
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => $e->getMessage(),
|
||||
], Response::HTTP_CONFLICT);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true, 'data' => $result]);
|
||||
}
|
||||
|
||||
public function reopen(Request $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->reopen($schoolYear, $this->getCurrentUserId()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function parentBalances(Request $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->parentBalances($schoolYear, $request->query('to_school_year')),
|
||||
]);
|
||||
}
|
||||
|
||||
public function promotionPreview(Request $request, int $schoolYear): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->service->promotionPreview($schoolYear, $request->query('to_school_year')),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?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'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user