siakad-itm/app/Http/Requests/Admin/Master/AcademicTermRequest.php

87 lines
3.5 KiB
PHP

<?php
namespace App\Http\Requests\Admin\Master;
use App\Enums\Semester;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class AcademicTermRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can($this->isMethod('post') ? 'create-academic-terms' : 'update-academic-terms');
}
public function rules(): array
{
return [
'academic_year' => [
'required',
'string',
'max:20',
function ($attribute, $value, $fail) {
if (! preg_match('/^(\d{4})\/(\d{4})$/', $value, $matches)) {
$fail('Format tahun ajaran harus YYYY/YYYY, contoh: 2025/2026.');
return;
}
$startYear = (int) $matches[1];
$endYear = (int) $matches[2];
if ($endYear !== $startYear + 1) {
$fail('Tahun kedua harus selisih 1 tahun dari tahun pertama. Contoh: 2025/2026, 2026/2027.');
}
},
],
'semester' => [
'required',
'string',
Rule::in(Semester::values()),
Rule::unique('academic_terms')->where(function ($query) {
return $query->where('academic_year', $this->input('academic_year'));
})->ignore($this->route('academic_term')),
],
'start_date' => [
'required',
'date',
function ($attribute, $value, $fail) {
$academicYear = $this->input('academic_year');
$semester = $this->input('semester');
if ($academicYear && preg_match('/^(\d{4})\/(\d{4})$/', $academicYear, $matches)) {
$startYear = (int) $matches[1];
$endYear = (int) $matches[2];
$dateYear = (int) date('Y', strtotime($value));
$expectedYear = $semester === 'even' ? $endYear : $startYear;
if ($dateYear !== $expectedYear) {
$fail('Start date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
}
}
},
],
'end_date' => [
'required',
'date',
'after_or_equal:start_date',
function ($attribute, $value, $fail) {
$academicYear = $this->input('academic_year');
$semester = $this->input('semester');
if ($academicYear && preg_match('/^(\d{4})\/(\d{4})$/', $academicYear, $matches)) {
$startYear = (int) $matches[1];
$endYear = (int) $matches[2];
$dateYear = (int) date('Y', strtotime($value));
$expectedYear = $semester === 'even' ? $endYear : $startYear;
if ($dateYear !== $expectedYear) {
$fail('End date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
}
}
},
],
'is_active' => ['boolean'],
'open_semesters' => ['nullable', 'array'],
'open_semesters.*' => ['integer', 'between:1,8'],
];
}
}