ADD SCHOOL YEAR MANAGEMENT
Tests / PHPUnit (push) Failing after 40s

This commit is contained in:
root
2026-07-12 02:21:39 -04:00
parent c7f67da9bf
commit e06ccc9cc0
36 changed files with 6722 additions and 327 deletions
@@ -0,0 +1,68 @@
<?php
namespace App\Services;
use App\Models\SchoolYearModel;
use DateTimeImmutable;
use InvalidArgumentException;
final class SchoolYearValidationService
{
public function __construct(
private readonly SchoolYearModel $schoolYearModel,
) {
}
public function validateMetadata(array $payload, ?int $exceptId = null): void
{
$name = trim((string) ($payload['name'] ?? ''));
if (! $this->isValidYearName($name)) {
throw new InvalidArgumentException('School year must use YYYY-YYYY with consecutive years.');
}
$existing = $this->schoolYearModel->where('name', $name);
if ($exceptId !== null) {
$existing->where('id !=', $exceptId);
}
if ($existing->first() !== null) {
throw new InvalidArgumentException('That school year already exists.');
}
$startsOn = $this->dateOrNull($payload['starts_on'] ?? null);
$endsOn = $this->dateOrNull($payload['ends_on'] ?? null);
if ($startsOn !== null && $endsOn !== null && $startsOn >= $endsOn) {
throw new InvalidArgumentException('School year start date must be before the end date.');
}
$registrationStarts = $this->dateOrNull($payload['registration_starts_on'] ?? null);
$registrationEnds = $this->dateOrNull($payload['registration_ends_on'] ?? null);
if ($registrationStarts !== null && $registrationEnds !== null && $registrationStarts > $registrationEnds) {
throw new InvalidArgumentException('Registration start date must be on or before the registration end date.');
}
}
public function isValidYearName(string $value): bool
{
if (! preg_match('/^(\d{4})-(\d{4})$/', $value, $matches)) {
return false;
}
return (int) $matches[2] === (int) $matches[1] + 1;
}
private function dateOrNull(mixed $value): ?DateTimeImmutable
{
$value = trim((string) $value);
if ($value === '') {
return null;
}
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $value);
if (! $date instanceof DateTimeImmutable || $date->format('Y-m-d') !== $value) {
throw new InvalidArgumentException('Dates must use YYYY-MM-DD.');
}
return $date;
}
}