Fix Pint formatting

This commit is contained in:
root
2026-06-09 01:25:14 -04:00
parent 6be4875c5e
commit 20a0b6c4e5
1485 changed files with 11318 additions and 10273 deletions
@@ -2,13 +2,13 @@
namespace App\Services;
use App\Models\AttendanceTracking;
use App\Models\StudentClass;
use App\Models\Student;
use App\Models\Configuration;
use App\Models\AttendanceData;
use App\Models\ParentNotification;
use App\Models\AttendanceEmailTemplate;
use App\Models\AttendanceTracking;
use App\Models\Configuration;
use App\Models\ParentNotification;
use App\Models\Student;
use App\Models\StudentClass;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
@@ -19,8 +19,11 @@ use Throwable;
class AttendanceTrackingService
{
protected string $semester;
protected string $schoolYear;
protected array $debugCompute = [];
protected ?array $attendanceReportedColumns = null;
public function __construct(
@@ -40,19 +43,19 @@ class AttendanceTrackingService
public function getPendingViolations(?string $schoolYearParam = null, ?string $semesterParam = null): array
{
$schoolYear = filled($schoolYearParam) ? (string) $schoolYearParam : (string) $this->schoolYear;
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
$semester = filled($semesterParam) ? (string) $semesterParam : null; // disabled like legacy
$debugInfo = [
'school_year_param' => $schoolYear,
'semester_param' => $semester,
'class_students' => 0,
'student_ids' => 0,
'attendance_rows' => 0,
'filtered_rows' => 0,
'violations' => 0,
'active_weeks' => 0,
'abs_last5' => 0,
'late_last5' => 0,
'semester_param' => $semester,
'class_students' => 0,
'student_ids' => 0,
'attendance_rows' => 0,
'filtered_rows' => 0,
'violations' => 0,
'active_weeks' => 0,
'abs_last5' => 0,
'late_last5' => 0,
];
$classStudentsQuery = $this->studentClassModel->query();
@@ -73,9 +76,9 @@ class AttendanceTrackingService
->orderByDesc('id')
->first();
if ($latestTerm && !empty($latestTerm->school_year)) {
if ($latestTerm && ! empty($latestTerm->school_year)) {
$schoolYear = (string) $latestTerm->school_year;
if (!empty($latestTerm->semester)) {
if (! empty($latestTerm->semester)) {
$semester = (string) $latestTerm->semester;
}
@@ -106,7 +109,7 @@ class AttendanceTrackingService
if (empty($studentIds) && empty($studentCodes)) {
$attendanceStudents = DB::table('attendance_data')
->selectRaw('DISTINCT student_id')
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->orderBy('student_id')
->get();
@@ -123,7 +126,7 @@ class AttendanceTrackingService
$studentIds = array_values(array_unique(array_filter($studentIds, fn ($v) => $v > 0)));
$studentCodes = array_values(array_unique(array_filter($studentCodes, fn ($v) => $v !== '')));
if (!empty($studentIds)) {
if (! empty($studentIds)) {
$inactiveRows = $this->studentModel->query()
->select('id')
->whereIn('id', $studentIds)
@@ -138,11 +141,11 @@ class AttendanceTrackingService
$studentIds = array_values(array_filter(
$studentIds,
static fn ($id) => !isset($inactiveIdSet[$id])
static fn ($id) => ! isset($inactiveIdSet[$id])
));
}
if (!empty($studentCodes)) {
if (! empty($studentCodes)) {
$inactiveCodeRows = $this->studentModel->query()
->select('school_id')
->whereIn('school_id', $studentCodes)
@@ -157,7 +160,7 @@ class AttendanceTrackingService
$studentCodes = array_values(array_filter(
$studentCodes,
static fn ($code) => $code !== '' && !isset($inactiveCodeSet[$code])
static fn ($code) => $code !== '' && ! isset($inactiveCodeSet[$code])
));
}
@@ -174,7 +177,7 @@ class AttendanceTrackingService
}
$students = [];
if (!empty($studentIds)) {
if (! empty($studentIds)) {
$students = $this->studentModel->query()
->whereIn('id', $studentIds)
->where('is_active', 1)
@@ -182,7 +185,7 @@ class AttendanceTrackingService
->toArray();
}
if (!empty($studentCodes)) {
if (! empty($studentCodes)) {
$byCode = $this->studentModel->query()
->whereIn('school_id', $studentCodes)
->where('is_active', 1)
@@ -192,7 +195,7 @@ class AttendanceTrackingService
$seen = array_flip(array_map(fn ($s) => (int) ($s['id'] ?? 0), $students));
foreach ($byCode as $s) {
$sid = (int) ($s['id'] ?? 0);
if ($sid > 0 && !isset($seen[$sid])) {
if ($sid > 0 && ! isset($seen[$sid])) {
$students[] = $s;
$seen[$sid] = true;
}
@@ -208,7 +211,7 @@ class AttendanceTrackingService
}
foreach ($studentCodes as $code) {
if (!isset($knownCodes[$code])) {
if (! isset($knownCodes[$code])) {
$virtualId = abs(crc32($code)) ?: random_int(1000000, 1999999);
$students[] = [
'id' => $virtualId,
@@ -244,7 +247,7 @@ class AttendanceTrackingService
foreach (array_merge($studentIds, $studentCodes) as $sidOrCode) {
if (is_numeric($sidOrCode)) {
$sid = (int) $sidOrCode;
if ($sid > 0 && !isset($existingIds[$sid])) {
if ($sid > 0 && ! isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => (string) $sid,
@@ -257,7 +260,7 @@ class AttendanceTrackingService
}
} else {
$code = (string) $sidOrCode;
if ($code !== '' && !isset($studentCodeToId[$code])) {
if ($code !== '' && ! isset($studentCodeToId[$code])) {
$virtualId = abs(crc32($code)) ?: random_int(2000000, 2999999);
$students[] = [
'id' => $virtualId,
@@ -295,14 +298,14 @@ class AttendanceTrackingService
'is_reported',
'is_notified',
])
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
->where(function ($q) use ($studentIds, $studentCodes) {
if (!empty($studentIds)) {
if (! empty($studentIds)) {
$q->whereIn('student_id', $studentIds);
}
if (!empty($studentCodes)) {
if (!empty($studentIds)) {
if (! empty($studentCodes)) {
if (! empty($studentIds)) {
$q->orWhereIn('student_id', $studentCodes);
} else {
$q->whereIn('student_id', $studentCodes);
@@ -322,16 +325,16 @@ class AttendanceTrackingService
if (empty($termRows)) {
$latestAttendanceTerm = DB::table('attendance_data')
->select('school_year', 'semester', 'date')
->when(!empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
->when(! empty($studentIds), fn ($q) => $q->whereIn('student_id', $studentIds))
->orderByDesc('date')
->first();
if ($latestAttendanceTerm) {
$schoolYear = !empty($latestAttendanceTerm->school_year)
$schoolYear = ! empty($latestAttendanceTerm->school_year)
? (string) $latestAttendanceTerm->school_year
: $schoolYear;
$semester = !empty($latestAttendanceTerm->semester)
$semester = ! empty($latestAttendanceTerm->semester)
? (string) $latestAttendanceTerm->semester
: $semester;
@@ -354,14 +357,14 @@ class AttendanceTrackingService
'is_reported',
'is_notified',
])
->when(!empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(!empty($semester), fn ($q) => $q->where('semester', $semester))
->when(! empty($schoolYear), fn ($q) => $q->where('school_year', $schoolYear))
->when(! empty($semester), fn ($q) => $q->where('semester', $semester))
->where(function ($q) use ($studentIds, $studentCodes) {
if (!empty($studentIds)) {
if (! empty($studentIds)) {
$q->whereIn('student_id', $studentIds);
}
if (!empty($studentCodes)) {
if (!empty($studentIds)) {
if (! empty($studentCodes)) {
if (! empty($studentIds)) {
$q->orWhereIn('student_id', $studentCodes);
} else {
$q->whereIn('student_id', $studentCodes);
@@ -392,7 +395,7 @@ class AttendanceTrackingService
$attendanceRows = [];
foreach ($termRows as $row) {
$dStr = $row['date'] ?? null;
if (!$dStr) {
if (! $dStr) {
continue;
}
@@ -402,7 +405,7 @@ class AttendanceTrackingService
continue;
}
if ($d->lt($start) || !$d->lt($endEx)) {
if ($d->lt($start) || ! $d->lt($endEx)) {
continue;
}
@@ -418,7 +421,7 @@ class AttendanceTrackingService
if ($sid === null) {
$sid = abs(crc32($code)) ?: random_int(3000000, 3999999);
$studentCodeToId[$code] = $sid;
if (!isset($existingIds[$sid])) {
if (! isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => $code,
@@ -443,7 +446,7 @@ class AttendanceTrackingService
foreach ($attendanceRows as $arow) {
$sid = (int) ($arow['student_id'] ?? 0);
if ($sid > 0 && !isset($existingIds[$sid])) {
if ($sid > 0 && ! isset($existingIds[$sid])) {
$students[] = [
'id' => $sid,
'school_id' => (string) ($arow['student_code'] ?? $arow['student_id']),
@@ -495,13 +498,13 @@ class AttendanceTrackingService
$parentEmail = $data['parent_email'] ?? '';
$parentName = $data['parent_name'] ?? '';
if (!$parentEmail) {
if (! $parentEmail) {
$parent = $this->getPrimaryParentForStudent($sid) ?? [];
$parentEmail = $parent['email'] ?? '';
$parentName = $parent['parent_name'] ?? '';
}
if (!$parentEmail) {
if (! $parentEmail) {
return [
'success' => false,
'message' => 'No parent email found for this student.',
@@ -552,7 +555,7 @@ class AttendanceTrackingService
try {
$this->attendanceMailerService->queueAttendanceEvent($payload);
if ($row && !empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
if ($row && ! empty($row['id']) && method_exists($this->attendanceTrackingModel, 'markAsNotified')) {
$this->attendanceTrackingModel->markAsNotified((int) $row['id']);
}
@@ -562,7 +565,7 @@ class AttendanceTrackingService
'data' => $payload,
];
} catch (Throwable $e) {
Log::error('Attendance record queue failed: ' . $e->getMessage());
Log::error('Attendance record queue failed: '.$e->getMessage());
return [
'success' => false,
@@ -582,7 +585,7 @@ class AttendanceTrackingService
?string $semesterFilter = null
): array {
$student = $this->studentModel->query()->find($studentId);
if (!$student) {
if (! $student) {
return [
'success' => false,
'message' => 'Student not found',
@@ -591,7 +594,7 @@ class AttendanceTrackingService
}
$student = $student->toArray();
$student['name'] = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
$student['name'] = trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? ''));
$codeParam = strtoupper((string) ($codeParam ?? ''));
$incidentDate = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $incidentDate) ? (string) $incidentDate : '';
@@ -656,7 +659,7 @@ class AttendanceTrackingService
])
->where(function ($q) use ($studentIdValues, $studentCodeValues) {
$q->whereIn('student_id', $studentIdValues);
if (!empty($studentCodeValues)) {
if (! empty($studentCodeValues)) {
$q->orWhereIn('student_id', $studentCodeValues);
}
})
@@ -674,7 +677,7 @@ class AttendanceTrackingService
if ($pendingOnly) {
$this->applyUnreportedAttendanceFilter($qb);
if (!$includeNotified) {
if (! $includeNotified) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_notified, ''))) NOT IN ('yes','1'))");
}
}
@@ -700,11 +703,11 @@ class AttendanceTrackingService
'semester' => $semester,
];
if ($data['violation_date'] === '' && !empty($data['attendance'][0]['date'])) {
if ($data['violation_date'] === '' && ! empty($data['attendance'][0]['date'])) {
$data['violation_date'] = substr((string) $data['attendance'][0]['date'], 0, 10);
}
if (!empty($data['attendance'][0]['is_notified'])) {
if (! empty($data['attendance'][0]['is_notified'])) {
$data['violation_notified'] = $data['attendance'][0]['is_notified'];
}
@@ -782,15 +785,17 @@ class AttendanceTrackingService
$to = trim((string) ($v['parent_email'] ?? ''));
$pname = (string) ($v['parent_name'] ?? '');
if ($sid <= 0 || !$code || !$date || !$to) {
if ($sid <= 0 || ! $code || ! $date || ! $to) {
$errors++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'missing data'];
continue;
}
if ($this->notificationAlreadySent($sid, $code, $date, 'email', $to)) {
$skipped++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'duplicate'];
continue;
}
@@ -811,7 +816,7 @@ class AttendanceTrackingService
$tpl = $this->renderTemplate($code, $variant, $context);
if (!$tpl) {
if (! $tpl) {
$subject = match ($code) {
'ABS_1' => 'Attendance Notice: Unreported Absence',
'LATE_2' => 'Attendance Notice: Repeated Lateness',
@@ -819,14 +824,14 @@ class AttendanceTrackingService
};
$studentName = (string) ($v['name'] ?? '');
$body = "<p>Dear " . ($pname ?: 'Parent/Guardian') . "</p>"
. "<p>We'd like to inform you about your student's recent attendance:</p>"
. "<ul>"
. "<li><strong>Student:</strong> {$studentName}</li>"
. "<li><strong>Issue:</strong> " . (string) ($v['violation'] ?? '') . "</li>"
. "<li><strong>As of:</strong> {$date}</li>"
. "</ul>"
. "<p>If you have any questions, please contact the school office.</p>";
$body = '<p>Dear '.($pname ?: 'Parent/Guardian').'</p>'
."<p>We'd like to inform you about your student's recent attendance:</p>"
.'<ul>'
."<li><strong>Student:</strong> {$studentName}</li>"
.'<li><strong>Issue:</strong> '.(string) ($v['violation'] ?? '').'</li>'
."<li><strong>As of:</strong> {$date}</li>"
.'</ul>'
.'<p>If you have any questions, please contact the school office.</p>';
} else {
[$subject, $body] = $tpl;
}
@@ -849,7 +854,7 @@ class AttendanceTrackingService
} catch (Throwable $e) {
$errors++;
$this->logNotification($sid, $code, $date, 'email', $to, $subject, 'failed', $e->getMessage());
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: ' . $e->getMessage()];
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'error: '.$e->getMessage()];
}
try {
@@ -875,7 +880,7 @@ class AttendanceTrackingService
}
} catch (Throwable $e) {
$errors++;
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: ' . $e->getMessage()];
$details[] = ['student_id' => $sid, 'code' => $code, 'date' => $date, 'result' => 'cc_error: '.$e->getMessage()];
}
if ($anyOk) {
@@ -895,10 +900,10 @@ class AttendanceTrackingService
$absDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['absences'] ?? []));
$lateDates = array_map(fn ($d) => substr((string) $d, 0, 10), (array) ($v['lates'] ?? []));
if (!empty($absDates)) {
if (! empty($absDates)) {
$allDates = array_merge($allDates, $absDates);
}
if (!empty($lateDates)) {
if (! empty($lateDates)) {
$allDates = array_merge($allDates, $lateDates);
}
if (empty($allDates)) {
@@ -1034,7 +1039,7 @@ class AttendanceTrackingService
foreach ($rows as $row) {
$sid = (int) ($row->student_id ?? 0);
if ($sid > 0 && !isset($classByStudent[$sid])) {
if ($sid > 0 && ! isset($classByStudent[$sid])) {
$classByStudent[$sid] = [
'class_section_id' => $row->class_section_id ?? null,
'class_section_name' => (string) ($row->class_section_name ?? ''),
@@ -1049,7 +1054,7 @@ class AttendanceTrackingService
$mergedData = [];
foreach ($trackingData as $row) {
$sid = (int) ($row['student_id'] ?? 0);
if (!isset($studentMap[$sid])) {
if (! isset($studentMap[$sid])) {
continue;
}
@@ -1057,7 +1062,7 @@ class AttendanceTrackingService
if (isset($classByStudent[$sid])) {
$merged['class_section_name'] = (string) ($classByStudent[$sid]['class_section_name'] ?? '');
$merged['class_name'] = (string) ($classByStudent[$sid]['class_name'] ?? '');
} elseif (!empty($merged['registration_grade'])) {
} elseif (! empty($merged['registration_grade'])) {
$merged['grade'] = (string) $merged['registration_grade'];
}
@@ -1101,7 +1106,7 @@ class AttendanceTrackingService
$violation = [
'id' => $studentId,
'name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
'name' => trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? '')),
'last_date' => $lastDate,
'violation' => $code,
'violation_code' => $code,
@@ -1110,7 +1115,7 @@ class AttendanceTrackingService
$ctx = $this->buildTemplateContext($violation, $parent);
$rendered = $this->renderTemplate($code, $variant, $ctx);
if (!$rendered) {
if (! $rendered) {
return [
'success' => false,
'message' => "Template not found for {$code} ({$variant}).",
@@ -1188,7 +1193,7 @@ class AttendanceTrackingService
$sec = $this->getSecondaryParentForStudent($sid);
$to2 = trim((string) ($sec['email'] ?? ''));
if ($to2 !== '' && strcasecmp($to2, $to) !== 0) {
if (!$this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
if (! $this->notificationAlreadySent($sid, $code, $ymd, 'email', $to2)) {
$ok2 = $this->attendanceMailerService->send($to2, $subject, $wrapped);
$this->logNotification(
$sid,
@@ -1206,7 +1211,7 @@ class AttendanceTrackingService
}
}
if (!$anyOk) {
if (! $anyOk) {
return [
'success' => false,
'message' => 'Failed to send email.',
@@ -1251,7 +1256,7 @@ class AttendanceTrackingService
return [
'success' => false,
'message' => 'Error: ' . $e->getMessage(),
'message' => 'Error: '.$e->getMessage(),
'status' => 500,
];
}
@@ -1273,7 +1278,7 @@ class AttendanceTrackingService
->where('id', $studentId)
->first();
if (!$stu) {
if (! $stu) {
return [
'success' => false,
'message' => 'Student not found',
@@ -1298,7 +1303,7 @@ class AttendanceTrackingService
] : null;
$pb = DB::table('parents')->where('firstparent_id', $primaryId);
if (!empty($schoolYear)) {
if (! empty($schoolYear)) {
$pb->where('school_year', $schoolYear);
}
@@ -1325,7 +1330,7 @@ class AttendanceTrackingService
}
}
if (!$secondary) {
if (! $secondary) {
$fallbackEmail = (string) ($pRow->secondparent_email ?? '');
$fallbackPhone = (string) ($pRow->secondparent_phone ?? '');
$fallbackFirst = (string) ($pRow->secondparent_firstname ?? '');
@@ -1351,7 +1356,7 @@ class AttendanceTrackingService
],
];
} catch (Throwable $e) {
Log::error('parentsInfo() failed: ' . $e->getMessage());
Log::error('parentsInfo() failed: '.$e->getMessage());
return [
'success' => false,
@@ -1379,11 +1384,11 @@ class AttendanceTrackingService
->where('school_year', $this->schoolYear)
->where('date', '>=', $start)
->where('date', '<', $end)
->where('reason', 'like', '%' . $code . '%')
->where('reason', 'like', '%'.$code.'%')
->orderByDesc('date')
->first();
if (!$row) {
if (! $row) {
$row = $this->attendanceTrackingModel->query()
->where('student_id', $sid)
->where('semester', $this->semester)
@@ -1394,7 +1399,7 @@ class AttendanceTrackingService
->first();
}
if ($row && !empty($row->id)) {
if ($row && ! empty($row->id)) {
DB::table($this->attendanceTrackingModel->getTable())
->where('id', (int) $row->id)
->update([
@@ -1426,7 +1431,7 @@ class AttendanceTrackingService
} catch (Throwable $e) {
return [
'success' => false,
'message' => 'Failed to save note: ' . $e->getMessage(),
'message' => 'Failed to save note: '.$e->getMessage(),
'status' => 500,
];
}
@@ -1450,13 +1455,14 @@ class AttendanceTrackingService
->where('incident_date', $ymd)
->where('channel', $channel);
if (!empty($to)) {
if (! empty($to)) {
$query->where('to_address', $to);
}
return $query->exists();
} catch (Throwable $e) {
Log::debug('notificationAlreadySent(): ' . $e->getMessage());
Log::debug('notificationAlreadySent(): '.$e->getMessage());
return false;
}
}
@@ -1479,7 +1485,7 @@ class AttendanceTrackingService
'channel' => $channel,
];
if (!empty($to)) {
if (! empty($to)) {
$where['to_address'] = $to;
}
@@ -1488,7 +1494,7 @@ class AttendanceTrackingService
->orderByDesc('id')
->first();
if ($existing && !empty($existing->id)) {
if ($existing && ! empty($existing->id)) {
$existing->update([
'subject' => $subject,
'status' => $status,
@@ -1512,7 +1518,7 @@ class AttendanceTrackingService
]);
}
} catch (Throwable $e) {
Log::debug('logNotification(): ' . $e->getMessage());
Log::debug('logNotification(): '.$e->getMessage());
}
}
@@ -1524,7 +1530,7 @@ class AttendanceTrackingService
->where('s.id', $studentId)
->first();
if (!$row || empty($row->user_id)) {
if (! $row || empty($row->user_id)) {
return null;
}
@@ -1544,7 +1550,7 @@ class AttendanceTrackingService
->where('id', $studentId)
->first();
if (!$stu) {
if (! $stu) {
return null;
}
@@ -1557,7 +1563,7 @@ class AttendanceTrackingService
}
$pRow = $pb->orderByDesc('updated_at')->first();
if (!$pRow) {
if (! $pRow) {
return null;
}
@@ -1568,11 +1574,11 @@ class AttendanceTrackingService
->where('id', $secondId)
->first();
if ($u2 && !empty($u2->email)) {
if ($u2 && ! empty($u2->email)) {
return [
'user_id' => (int) $u2->id,
'email' => (string) $u2->email,
'parent_name' => trim(($u2->firstname ?? '') . ' ' . ($u2->lastname ?? '')),
'parent_name' => trim(($u2->firstname ?? '').' '.($u2->lastname ?? '')),
'phone' => (string) ($u2->cellphone ?? ''),
];
}
@@ -1587,12 +1593,12 @@ class AttendanceTrackingService
return [
'user_id' => $secondId ?: null,
'email' => $fallbackEmail,
'parent_name' => trim($fallbackFirst . ' ' . $fallbackLast) ?: null,
'parent_name' => trim($fallbackFirst.' '.$fallbackLast) ?: null,
'phone' => $fallbackPhone,
];
}
} catch (Throwable $e) {
Log::error('getSecondaryParentForStudent() failed: ' . $e->getMessage());
Log::error('getSecondaryParentForStudent() failed: '.$e->getMessage());
}
return null;
@@ -1631,7 +1637,7 @@ class AttendanceTrackingService
$ymd = substr((string) ($r['date'] ?? ''), 0, 10);
$stat = strtolower(trim((string) ($r['status'] ?? '')));
if (!in_array($stat, ['absent', 'late'], true)) {
if (! in_array($stat, ['absent', 'late'], true)) {
continue;
}
@@ -1643,10 +1649,10 @@ class AttendanceTrackingService
[$syStart, $syEnd] = $this->deriveSchoolYearBounds($schoolYear);
$weekRowsSource = null;
if (!empty($weekRowsFallback)) {
if (! empty($weekRowsFallback)) {
foreach ($weekRowsFallback as $r) {
$st = strtolower(trim((string) ($r['status'] ?? '')));
if ($st !== '' && !in_array($st, ['absent', 'late'], true)) {
if ($st !== '' && ! in_array($st, ['absent', 'late'], true)) {
$weekRowsSource = $weekRowsFallback;
break;
}
@@ -1679,6 +1685,7 @@ class AttendanceTrackingService
}
$out = array_values(array_unique($out));
rsort($out);
return $out;
};
@@ -1689,7 +1696,7 @@ class AttendanceTrackingService
$students
)));
if (!empty($studentIdsForClass)) {
if (! empty($studentIdsForClass)) {
$rows = DB::table('student_class as sc')
->select([
'sc.student_id',
@@ -1707,7 +1714,7 @@ class AttendanceTrackingService
foreach ($rows as $row) {
$sid = (int) ($row->student_id ?? 0);
if ($sid > 0 && !isset($classByStudent[$sid])) {
if ($sid > 0 && ! isset($classByStudent[$sid])) {
$classByStudent[$sid] = [
'class_section_id' => $row->class_section_id ?? null,
'class_section_name' => (string) ($row->class_section_name ?? ''),
@@ -1718,7 +1725,7 @@ class AttendanceTrackingService
}
}
} catch (Throwable $e) {
Log::debug('computeViolations(): class prefetch failed: ' . $e->getMessage());
Log::debug('computeViolations(): class prefetch failed: '.$e->getMessage());
}
$out = [];
@@ -1727,7 +1734,7 @@ class AttendanceTrackingService
foreach ($students as $stu) {
$sid = (int) ($stu['id'] ?? 0);
$name = trim(($stu['firstname'] ?? '') . ' ' . ($stu['lastname'] ?? ''));
$name = trim(($stu['firstname'] ?? '').' '.($stu['lastname'] ?? ''));
$absDatesAll = array_values(array_unique($byStudent[$sid]['absent'] ?? []));
$lateDatesAll = array_values(array_unique($byStudent[$sid]['late'] ?? []));
@@ -1745,7 +1752,7 @@ class AttendanceTrackingService
$lateCountLast5 += count($lateDates);
$absenceViolation = null;
if (!empty($absDates)) {
if (! empty($absDates)) {
$lastAbsDate = $absDates[0];
$A2row = $this->hasNConsecutiveItems($absDates, 2, 7);
$A3row = $this->hasNConsecutiveItems($absDates, 3, 7);
@@ -1792,7 +1799,7 @@ class AttendanceTrackingService
}
$lateViolation = null;
if (!empty($lateDates)) {
if (! empty($lateDates)) {
$lastLateDate = $lateDates[0];
$L2row = $this->hasNConsecutiveItems($lateDates, 2, 7);
@@ -1807,7 +1814,7 @@ class AttendanceTrackingService
$lateWeeksSet = array_flip($lateWeekIdx);
$lateCoversAllWindowWeeks = true;
for ($i = $windowStartIdx; $i <= $currentWeekIdx; $i++) {
if (!isset($lateWeeksSet[$i])) {
if (! isset($lateWeeksSet[$i])) {
$lateCoversAllWindowWeeks = false;
break;
}
@@ -1858,7 +1865,7 @@ class AttendanceTrackingService
$chosen = $this->chooseHigherSeverity($absenceViolation, $lateViolation);
if (!$chosen && count($absDates) === 1) {
if (! $chosen && count($absDates) === 1) {
$chosen = [
'type' => 'absence',
'code' => 'ABS_1',
@@ -1871,7 +1878,7 @@ class AttendanceTrackingService
];
}
if (!$chosen) {
if (! $chosen) {
continue;
}
@@ -1883,7 +1890,7 @@ class AttendanceTrackingService
->where('school_year', $schoolYear)
->where('date', '>=', $start)
->where('date', '<', $end)
->where('reason', 'like', '%' . $chosen['code'] . '%');
->where('reason', 'like', '%'.$chosen['code'].'%');
if ($semester !== null) {
$trackingQ->where('semester', $semester);
@@ -1897,7 +1904,7 @@ class AttendanceTrackingService
$cls = $classByStudent[$sid] ?? [];
$classLabel = (string) ($cls['class_section_name'] ?? '');
if ($classLabel === '' && !empty($cls['class_name'])) {
if ($classLabel === '' && ! empty($cls['class_name'])) {
$classLabel = (string) $cls['class_name'];
}
@@ -1947,6 +1954,7 @@ class AttendanceTrackingService
if ($a && $b) {
if ($a['severity'] === $b['severity']) {
$prio = ['expel_notify' => 3, 'team_notify' => 2, 'auto_email' => 1];
return ($prio[$a['action']] ?? 0) >= ($prio[$b['action']] ?? 0) ? $a : $b;
}
@@ -1976,11 +1984,11 @@ class AttendanceTrackingService
{
$cols = $this->attendanceReportedColumns();
if (!empty($cols['is_reported'])) {
if (! empty($cols['is_reported'])) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(is_reported, ''))) NOT IN ('yes','1','true','y','on'))");
}
if (!empty($cols['reported'])) {
if (! empty($cols['reported'])) {
$qb->whereRaw("(LOWER(TRIM(COALESCE(reported, ''))) NOT IN ('yes','1','true','y','on'))");
}
@@ -2002,9 +2010,10 @@ class AttendanceTrackingService
protected function dayBounds(string $ymd): array
{
$d = substr($ymd, 0, 10);
return [
$d . ' 00:00:00',
date('Y-m-d', strtotime($d . ' +1 day')) . ' 00:00:00',
$d.' 00:00:00',
date('Y-m-d', strtotime($d.' +1 day')).' 00:00:00',
];
}
@@ -2024,9 +2033,10 @@ class AttendanceTrackingService
protected function deriveSchoolYearBounds(string $schoolYear): array
{
if (!preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
if (! preg_match('/^(\d{4})-(\d{4})$/', $schoolYear, $m)) {
$y = (int) date('Y');
$startY = (int) (date('n') >= 8 ? $y : $y - 1);
return [sprintf('%d-08-01', $startY), sprintf('%d-07-31', $startY + 1)];
}
@@ -2066,7 +2076,7 @@ class AttendanceTrackingService
->where('is_active', 1)
->first();
if (!$row) {
if (! $row) {
$row = $this->attendanceEmailTemplateModel->query()
->where('code', $code)
->where('variant', 'default')
@@ -2077,7 +2087,7 @@ class AttendanceTrackingService
$row = $row?->toArray();
}
if (!$row) {
if (! $row) {
return null;
}
@@ -2135,10 +2145,10 @@ class AttendanceTrackingService
$semester = ($semester !== null && $semester !== '') ? (string) $semester : null;
$weeks = [];
if (!empty($weekRowsFallback)) {
if (! empty($weekRowsFallback)) {
foreach ($weekRowsFallback as $r) {
$d = $r['date'] ?? null;
if (!$d) {
if (! $d) {
continue;
}
$ts = strtotime($d);
@@ -2195,25 +2205,38 @@ class AttendanceTrackingService
}
$idx = array_keys($set);
sort($idx);
return $idx;
}
protected function windowWeeksForViolationCode(string $code): int
{
$code = strtoupper(trim($code));
if ($code === '') return 5;
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) return 3;
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) return 4;
if (Str::startsWith($code, 'LATE_4')) return 4;
if (Str::startsWith($code, 'ABS_4')) return 5;
if ($code === '') {
return 5;
}
if (Str::startsWith($code, 'ABS_2') || Str::startsWith($code, 'LATE_2')) {
return 3;
}
if (Str::startsWith($code, 'ABS_3') || Str::startsWith($code, 'LATE_3') || Str::startsWith($code, 'MIX')) {
return 4;
}
if (Str::startsWith($code, 'LATE_4')) {
return 4;
}
if (Str::startsWith($code, 'ABS_4')) {
return 5;
}
return 5;
}
protected function isoWeekStartYmd(string $weekKey): string
{
if (preg_match('/^(\d{4})-W(\d{2})$/', $weekKey, $m)) {
return date('Y-m-d', strtotime($m[1] . '-W' . $m[2] . '-1'));
return date('Y-m-d', strtotime($m[1].'-W'.$m[2].'-1'));
}
return date('Y-m-d');
}
@@ -2234,14 +2257,15 @@ class AttendanceTrackingService
if (empty($activeWeekKeys)) {
$days = ($windowWeeks * 7) - 1;
return date('Y-m-d', strtotime($endBound . ' -' . $days . ' days'));
return date('Y-m-d', strtotime($endBound.' -'.$days.' days'));
}
$activeWeekKeys = array_values($activeWeekKeys);
$weekIndex = array_flip($activeWeekKeys);
$endWeekKey = date('o-\WW', strtotime($endBound));
if (!isset($weekIndex[$endWeekKey])) {
if (! isset($weekIndex[$endWeekKey])) {
$endWeekKey = null;
for ($i = count($activeWeekKeys) - 1; $i >= 0; $i--) {
$wkStart = $this->isoWeekStartYmd($activeWeekKeys[$i]);
@@ -2265,7 +2289,9 @@ class AttendanceTrackingService
protected function hasNConsecutiveItems(array $datesDesc, int $n, int $daysApart): bool
{
$N = count($datesDesc);
if ($N < $n) return false;
if ($N < $n) {
return false;
}
$dates = $datesDesc;
sort($dates);
@@ -2278,7 +2304,9 @@ class AttendanceTrackingService
if ($diff === $daysApart) {
$run++;
if ($run >= $n) return true;
if ($run >= $n) {
return true;
}
} else {
$run = 1;
}
@@ -2290,7 +2318,9 @@ class AttendanceTrackingService
protected function hasNInWActiveWeeks(array $weekIdx, int $n, int $w): bool
{
$N = count($weekIdx);
if ($N < $n) return false;
if ($N < $n) {
return false;
}
$l = 0;
for ($r = 0; $r < $N; $r++) {
@@ -2307,7 +2337,9 @@ class AttendanceTrackingService
protected function twoLatesOneAbsInWWeeks(array $lateIdx, array $absIdx, int $w): bool
{
if (count($lateIdx) < 2 || count($absIdx) < 1) return false;
if (count($lateIdx) < 2 || count($absIdx) < 1) {
return false;
}
$L = $lateIdx;
$A = $absIdx;
@@ -2322,6 +2354,7 @@ class AttendanceTrackingService
if ($L[$iL2] > $windowEnd) {
$iL1++;
$iL2 = $iL1 + 1;
continue;
}
@@ -2342,4 +2375,4 @@ class AttendanceTrackingService
return false;
}
}
}