add test batches
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user