add tests batch 20

This commit is contained in:
root
2026-06-09 01:03:53 -04:00
parent 95efb9652e
commit 6be4875c5e
1502 changed files with 13797 additions and 11313 deletions
@@ -2,14 +2,12 @@
namespace App\Services\Parents;
use App\Controllers\View\ParentAttendanceReportController;
use App\Http\Controllers\Api\Reports\FilesController;
use App\Models\AttendanceData;
use App\Models\AttendanceRecord;
use App\Models\ClassSection;
use App\Models\EarlyDismissalSignature;
use App\Models\ParentAttendanceReport;
use App\Models\Student;
use App\Models\ClassSection;
use App\Services\SemesterRangeService;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
@@ -20,7 +18,8 @@ class ParentAttendanceReportService
private ParentConfigService $configService,
private ParentAttendanceReportCalendarService $calendarService,
private SemesterRangeService $semesterRangeService
) {}
) {
}
public function formData(int $parentId): array
{
@@ -91,7 +90,7 @@ class ParentAttendanceReportService
}
$type = (string) ($payload['type'] ?? '');
if (! in_array($type, ['absent', 'late', 'early_dismissal'], true)) {
if (!in_array($type, ['absent', 'late', 'early_dismissal'], true)) {
throw new \RuntimeException('Invalid report type.');
}
@@ -105,8 +104,8 @@ class ParentAttendanceReportService
foreach ($rawDates as $entry) {
$dt = \DateTime::createFromFormat('Y-m-d', $entry);
if (! $dt) {
throw new \RuntimeException('Invalid date selected: '.$entry);
if (!$dt) {
throw new \RuntimeException('Invalid date selected: ' . $entry);
}
if ((int) $dt->format('w') !== 0) {
throw new \RuntimeException('Please select Sunday dates only.');
@@ -120,10 +119,10 @@ class ParentAttendanceReportService
$validDates[$entry] = $dt;
}
if ($type === 'late' && (! is_string($arrivalTime) || $arrivalTime === '')) {
if ($type === 'late' && (!is_string($arrivalTime) || $arrivalTime === '')) {
throw new \RuntimeException('Please provide an expected arrival time for late reporting.');
}
if ($type === 'early_dismissal' && (! is_string($dismissTime) || $dismissTime === '')) {
if ($type === 'early_dismissal' && (!is_string($dismissTime) || $dismissTime === '')) {
throw new \RuntimeException('Please provide a dismissal time for early dismissal.');
}
if ($type !== 'early_dismissal') {
@@ -148,7 +147,7 @@ class ParentAttendanceReportService
->first();
$classSectionId = $sectionRow->class_section_id ?? null;
$student = Student::query()->select('firstname', 'lastname')->find($sid);
$studentName = $student ? trim($student->firstname.' '.$student->lastname) : ('Student #'.$sid);
$studentName = $student ? trim($student->firstname . ' ' . $student->lastname) : ('Student #' . $sid);
$classLabel = $this->resolveClassSectionLabel($classSectionId);
foreach ($validDates as $reportDate => $_dt) {
@@ -164,7 +163,7 @@ class ParentAttendanceReportService
->whereIn('type', ['absent', 'late'])
->first();
if ($existingAL) {
$blocked[] = $studentName.' ('.$reportDate.')';
$blocked[] = $studentName . ' (' . $reportDate . ')';
} else {
$existingED = (clone $qb)->where('type', 'early_dismissal')->first();
if ($existingED) {
@@ -196,7 +195,7 @@ class ParentAttendanceReportService
->whereIn('type', ['absent', 'late', 'early_dismissal'])
->first();
if ($existingAny) {
$blocked[] = $studentName.' ('.$reportDate.')';
$blocked[] = $studentName . ' (' . $reportDate . ')';
} else {
ParentAttendanceReport::query()->create([
'parent_id' => $parentId,
@@ -243,8 +242,8 @@ class ParentAttendanceReportService
}
if ($inserted <= 0) {
$err = ! empty($blocked)
? ('Already submitted and cannot be changed for: '.implode(', ', array_slice($blocked, 0, 5)).(count($blocked) > 5 ? '…' : ''))
$err = !empty($blocked)
? ('Already submitted and cannot be changed for: ' . implode(', ', array_slice($blocked, 0, 5)) . (count($blocked) > 5 ? '…' : ''))
: 'Could not save your report. Please try again.';
throw new \RuntimeException($err);
}
@@ -279,7 +278,7 @@ class ParentAttendanceReportService
})));
$type = (string) ($payload['type'] ?? '');
if (empty($dateValues) || ! in_array($type, ['absent', 'late', 'early_dismissal'], true)) {
if (empty($dateValues) || !in_array($type, ['absent', 'late', 'early_dismissal'], true)) {
throw new \RuntimeException('Invalid date or type.');
}
@@ -313,7 +312,7 @@ class ParentAttendanceReportService
if ($sid <= 0) {
continue;
}
if (! isset($map[$sid])) {
if (!isset($map[$sid])) {
$map[$sid] = [
'student_id' => $sid,
'firstname' => (string) ($row['firstname'] ?? ''),
@@ -327,7 +326,7 @@ class ParentAttendanceReportService
}
$map[$sid]['dates'][$dVal] = $map[$sid]['dates'][$dVal] ?? [];
$t = (string) ($row['type'] ?? '');
if ($t !== '' && ! in_array($t, $map[$sid]['dates'][$dVal], true)) {
if ($t !== '' && !in_array($t, $map[$sid]['dates'][$dVal], true)) {
$map[$sid]['dates'][$dVal][] = $t;
}
}
@@ -338,7 +337,7 @@ class ParentAttendanceReportService
public function updateReport(int $parentId, int $reportId, array $payload): void
{
$row = ParentAttendanceReport::query()->find($reportId);
if (! $row || (int) $row->parent_id !== $parentId) {
if (!$row || (int) $row->parent_id !== $parentId) {
throw new \RuntimeException('Report not found.');
}
@@ -348,7 +347,7 @@ class ParentAttendanceReportService
$tzName = (string) (config('School')->attendance['timezone'] ?? 'UTC');
$tz = new \DateTimeZone($tzName ?: 'UTC');
$cutoff = new \DateTime($row->report_date.' 09:00:00', $tz);
$cutoff = new \DateTime($row->report_date . ' 09:00:00', $tz);
$now = new \DateTime('now', $tz);
if ($now >= $cutoff) {
throw new \RuntimeException('Editing window closed at 9:00 AM on the report date.');
@@ -364,13 +363,13 @@ class ParentAttendanceReportService
];
if ($type === 'late' && $arrival !== '') {
if (! preg_match('/^\\d{2}:\\d{2}(:\\d{2})?$/', $arrival)) {
if (!preg_match('/^\\d{2}:\\d{2}(:\\d{2})?$/', $arrival)) {
throw new \RuntimeException('Invalid arrival time format.');
}
$update['arrival_time'] = $arrival;
}
if ($type === 'early_dismissal' && $dismiss !== '') {
if (! preg_match('/^\\d{2}:\\d{2}(:\\d{2})?$/', $dismiss)) {
if (!preg_match('/^\\d{2}:\\d{2}(:\\d{2})?$/', $dismiss)) {
throw new \RuntimeException('Invalid dismissal time format.');
}
$update['dismiss_time'] = $dismiss;
@@ -386,7 +385,7 @@ class ParentAttendanceReportService
/**
* Staff index: early dismissal rows grouped by date (+ signature metadata per date).
*
* Parity with legacy {@see ParentAttendanceReportController::earlyDismissals}.
* Parity with legacy {@see \App\Controllers\View\ParentAttendanceReportController::earlyDismissals}.
*
* @return array{groups: array<string, array<int, array<string, mixed>>>, school_year: string, semester: string, signature_by_date: array<string, array<string, mixed>>}
*/
@@ -468,7 +467,7 @@ class ParentAttendanceReportService
}
/**
* Parity with legacy {@see ParentAttendanceReportController::addEarlyDismissalForm}.
* Parity with legacy {@see \App\Controllers\View\ParentAttendanceReportController::addEarlyDismissalForm}.
*
* @return array{students: array<int, array<string, mixed>>, default_date: string, school_year: string, semester: string}
*/
@@ -506,7 +505,7 @@ class ParentAttendanceReportService
}
/**
* Parity with legacy {@see ParentAttendanceReportController::saveEarlyDismissal}.
* Parity with legacy {@see \App\Controllers\View\ParentAttendanceReportController::saveEarlyDismissal}.
*/
public function saveStaffEarlyDismissal(int $studentId, string $reportDate, string $dismissTime, string $reason): void
{
@@ -574,8 +573,8 @@ class ParentAttendanceReportService
}
/**
* Parity with legacy {@see ParentAttendanceReportController::uploadEarlyDismissalSignature}.
* Files live under {@see storage_path('uploads/early_dismissal_signatures')} (same as {@see FilesController::earlyDismissalSignature}).
* Parity with legacy {@see \App\Controllers\View\ParentAttendanceReportController::uploadEarlyDismissalSignature}.
* Files live under {@see storage_path('uploads/early_dismissal_signatures')} (same as {@see \App\Http\Controllers\Api\Reports\FilesController::earlyDismissalSignature}).
*/
public function storeEarlyDismissalSignature(
UploadedFile $file,
@@ -645,7 +644,7 @@ class ParentAttendanceReportService
$oldFile = (string) ($existing->filename ?? '');
$existing->update($payload);
if ($oldFile !== '' && $oldFile !== $filename) {
@unlink($targetDir.DIRECTORY_SEPARATOR.$oldFile);
@unlink($targetDir . DIRECTORY_SEPARATOR . $oldFile);
}
} else {
EarlyDismissalSignature::query()->create($payload);
@@ -681,7 +680,7 @@ class ParentAttendanceReportService
return;
}
if (! $classSectionId) {
if (!$classSectionId) {
$row = DB::table('student_class')
->select('class_section_id')
->where('student_id', $studentId)
@@ -704,19 +703,19 @@ class ParentAttendanceReportService
$reasonParts = ['Parent-reported'];
if ($type === 'late' && $arrivalTime) {
$reasonParts[] = 'ETA '.substr($arrivalTime, 0, 5);
$reasonParts[] = 'ETA ' . substr($arrivalTime, 0, 5);
}
if (! empty($reason)) {
if (!empty($reason)) {
$reasonParts[] = trim($reason);
}
$reasonText = implode(' — ', $reasonParts);
if (! $existing) {
if (!$existing) {
$classId = ClassSection::query()
->where('class_section_id', $classSectionId)
->value('class_id');
$schoolId = Student::query()->whereKey($studentId)->value('school_id');
if (! $classId || ! $schoolId) {
if (!$classId || !$schoolId) {
return;
}
AttendanceData::query()->create([
@@ -731,7 +730,6 @@ class ParentAttendanceReportService
'school_year' => $schoolYear,
]);
$this->bumpAttendanceRecord($studentId, $classSectionId, $schoolId, $status, $semester, $schoolYear);
return;
}
@@ -773,7 +771,6 @@ class ParentAttendanceReportService
$updates['total_late']++;
}
$record->update($updates);
return;
}