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
@@ -3,14 +3,11 @@
namespace App\Services\Attendance;
use DateTimeImmutable;
use DateTimeZone;
use Illuminate\Support\Facades\DB;
class AttendanceAutoPublishJobService
{
public function __construct(private AttendanceAutoPublishService $autoPublish)
{
}
public function __construct(private AttendanceAutoPublishService $autoPublish) {}
public function run(?DateTimeImmutable $now = null): array
{
@@ -2,6 +2,7 @@
namespace App\Services\Attendance;
use Config\School;
use DateTimeImmutable;
use DateTimeZone;
@@ -9,7 +10,7 @@ class AttendanceAutoPublishService
{
public function timezone(?string $tzFromCfg = null): DateTimeZone
{
$tz = $tzFromCfg ?: (class_exists(\Config\School::class)
$tz = $tzFromCfg ?: (class_exists(School::class)
? (config('School')->attendance['timezone'] ?? null)
: null);
@@ -19,7 +20,7 @@ class AttendanceAutoPublishService
public function secondSundayAfterEndOfDay(string $ymd, ?string $tz = null): string
{
$zone = $this->timezone($tz);
$day = new DateTimeImmutable($ymd . ' 00:00:00', $zone);
$day = new DateTimeImmutable($ymd.' 00:00:00', $zone);
$weekday = (int) $day->format('w');
$daysToNextSunday = (7 - $weekday) % 7;
@@ -29,13 +29,13 @@ class AttendanceCommentService
$lastChar = $name !== '' ? substr($name, -1) : '';
$namePossessive = ($name === 'This student')
? "This student's"
: ($lastChar === 's' || $lastChar === 'S' ? ($name . "'") : ($name . "'s"));
: ($lastChar === 's' || $lastChar === 'S' ? ($name."'") : ($name."'s"));
if (strpos($text, '{name}') !== false) {
return str_replace('{name}', $namePossessive, $text);
}
return $namePossessive . ' ' . $text;
return $namePossessive.' '.$text;
}
public function templateForScore(float $score): ?array
@@ -12,8 +12,7 @@ class AttendanceConsequenceService
public function __construct(
private EmailService $emailService,
private UserNotificationDispatchService $notifier
) {
}
) {}
public function sendFollowUp(array $payload): array
{
@@ -55,10 +54,10 @@ class AttendanceConsequenceService
string $_viewName,
string $logLevel
): array {
$studentName = trim((string) ($payload['student']['firstname'] ?? '') . ' ' . (string) ($payload['student']['lastname'] ?? ''));
$studentName = trim((string) ($payload['student']['firstname'] ?? '').' '.(string) ($payload['student']['lastname'] ?? ''));
$parentEmail = (string) ($payload['parent']['email'] ?? '');
$parentName = (string) ($payload['parent']['name'] ?? '');
$teacherName = trim((string) ($payload['teacher']['firstname'] ?? '') . ' ' . (string) ($payload['teacher']['lastname'] ?? ''));
$teacherName = trim((string) ($payload['teacher']['firstname'] ?? '').' '.(string) ($payload['teacher']['lastname'] ?? ''));
$className = (string) ($payload['class']['class_section_name'] ?? '');
$semester = (string) ($payload['semester'] ?? '');
$schoolYear = (string) ($payload['school_year'] ?? '');
@@ -69,6 +68,7 @@ class AttendanceConsequenceService
Log::warning("Attendance {$type}: missing parent email", [
'student_id' => $payload['student_id'] ?? null,
]);
return ['ok' => false, 'message' => 'Missing parent email.'];
}
@@ -76,21 +76,21 @@ class AttendanceConsequenceService
$html = trim((string) ($payload['html'] ?? ''));
if ($html === '') {
$period = trim($semester . ' ' . $schoolYear);
$html = '<p>' . e($subject) . '</p>'
. '<p><strong>Student:</strong> ' . e($studentName) . '</p>'
. '<p><strong>Parent:</strong> ' . e($parentName) . '</p>'
. '<p><strong>Teacher:</strong> ' . e($teacherName) . '</p>'
. '<p><strong>Class:</strong> ' . e($className) . '</p>'
. ($period !== '' ? '<p><strong>Term:</strong> ' . e($period) . '</p>' : '')
. '<p><strong>Date:</strong> ' . e($dateFmt) . '</p>';
$period = trim($semester.' '.$schoolYear);
$html = '<p>'.e($subject).'</p>'
.'<p><strong>Student:</strong> '.e($studentName).'</p>'
.'<p><strong>Parent:</strong> '.e($parentName).'</p>'
.'<p><strong>Teacher:</strong> '.e($teacherName).'</p>'
.'<p><strong>Class:</strong> '.e($className).'</p>'
.($period !== '' ? '<p><strong>Term:</strong> '.e($period).'</p>' : '')
.'<p><strong>Date:</strong> '.e($dateFmt).'</p>';
}
$ok = false;
try {
$ok = $this->emailService->send($parentEmail, $subject, $html, 'attendance');
} catch (\Throwable $e) {
Log::error('Attendance email send failed: ' . $e->getMessage());
Log::error('Attendance email send failed: '.$e->getMessage());
}
$summary = $this->buildInAppSummary($type, $studentName, $dateFmt);
@@ -106,11 +106,11 @@ class AttendanceConsequenceService
);
}
if (!empty($payload['tracking_id'])) {
if (! empty($payload['tracking_id'])) {
AttendanceTracking::markAsNotified((int) $payload['tracking_id']);
}
Log::log($logLevel, "Attendance {$type} email " . ($ok ? 'sent' : 'failed'), [
Log::log($logLevel, "Attendance {$type} email ".($ok ? 'sent' : 'failed'), [
'student_id' => $payload['student_id'] ?? null,
'recipient' => $parentEmail,
]);
@@ -122,7 +122,8 @@ class AttendanceConsequenceService
{
$name = $studentName !== '' ? "{$studentName}" : '';
$date = $dateFmt !== '' ? " ({$dateFmt})" : '';
return $base . $name . $date;
return $base.$name.$date;
}
private function buildInAppSummary(string $type, string $studentName, string $dateFmt): string
@@ -11,18 +11,19 @@ class AttendanceDailySummaryService
public function __construct(
private UserNotificationDispatchService $notifier,
private EmailService $emailService
) {
}
) {}
public function sendAbsenteesSummary(): int
{
$rows = $this->fetchTodaySummary('absent');
return $this->notifyParents($rows, 'absent');
}
public function sendLatesSummary(): int
{
$rows = $this->fetchTodaySummary('late');
return $this->notifyParents($rows, 'late');
}
@@ -49,12 +50,12 @@ class AttendanceDailySummaryService
if ($type === 'absent') {
$query->where(function ($w) {
$w->whereIn(DB::raw("UPPER(TRIM(ad.status))"), ['ABSENT', 'ABS', 'A'])
$w->whereIn(DB::raw('UPPER(TRIM(ad.status))'), ['ABSENT', 'ABS', 'A'])
->orWhereRaw("UPPER(TRIM(ad.status)) LIKE 'ABS%'");
});
} else {
$query->where(function ($w) {
$w->whereIn(DB::raw("UPPER(TRIM(ad.status))"), ['LATE', 'L'])
$w->whereIn(DB::raw('UPPER(TRIM(ad.status))'), ['LATE', 'L'])
->orWhereRaw("UPPER(TRIM(ad.status)) LIKE 'LATE%'");
});
}
@@ -71,7 +72,7 @@ class AttendanceDailySummaryService
continue;
}
$studentName = trim((string) ($row['student_firstname'] ?? '') . ' ' . (string) ($row['student_lastname'] ?? ''));
$studentName = trim((string) ($row['student_firstname'] ?? '').' '.(string) ($row['student_lastname'] ?? ''));
$date = substr((string) ($row['date'] ?? ''), 0, 10);
$message = sprintf(
@@ -85,7 +86,7 @@ class AttendanceDailySummaryService
$email = (string) ($row['parent_email'] ?? '');
if ($email !== '') {
$body = '<p>' . e($message) . '</p>';
$body = '<p>'.e($message).'</p>';
$this->emailService->send($email, 'Daily Attendance Update', $body, 'attendance');
}
@@ -3,15 +3,14 @@
namespace App\Services\Attendance;
use App\Models\Role;
use Illuminate\Contracts\Auth\Authenticatable;
class AttendancePolicyService
{
public function canEditDay(array $dayRow, array $currentUser): bool
{
$status = strtolower((string)($dayRow['status'] ?? 'draft'));
$roles = array_map([$this, 'normalizeRole'], (array)($currentUser['roles'] ?? []));
$permissions = array_map('strtolower', (array)($currentUser['permissions'] ?? []));
$status = strtolower((string) ($dayRow['status'] ?? 'draft'));
$roles = array_map([$this, 'normalizeRole'], (array) ($currentUser['roles'] ?? []));
$permissions = array_map('strtolower', (array) ($currentUser['permissions'] ?? []));
$isAdmin = $this->isAdminLike($roles, $permissions);
$isTeacher = in_array('teacher', $roles, true) || in_array('ta', $roles, true) || in_array('teacher_assistant', $roles, true);
@@ -34,6 +33,7 @@ class AttendancePolicyService
public function isTeacher(array $roles): bool
{
$roles = array_map([$this, 'normalizeRole'], $roles);
return in_array('teacher', $roles, true)
|| in_array('ta', $roles, true)
|| in_array('teacher_assistant', $roles, true)
@@ -45,7 +45,7 @@ class AttendancePolicyService
$roles = array_map([$this, 'normalizeRole'], $roles);
$adminTokens = $this->adminRoleTokens();
if (!empty($adminTokens) && count(array_intersect($roles, $adminTokens)) > 0) {
if (! empty($adminTokens) && count(array_intersect($roles, $adminTokens)) > 0) {
return true;
}
@@ -61,7 +61,7 @@ class AttendancePolicyService
public function normalizeRole(?string $role): string
{
return str_replace([' ', '-'], '_', strtolower(trim((string)$role)));
return str_replace([' ', '-'], '_', strtolower(trim((string) $role)));
}
public function canManageEarlyDismissals(array $userRoles): bool
@@ -123,6 +123,7 @@ class AttendancePolicyService
}
$cache = array_keys($tokens);
return $cache;
}
}
@@ -42,7 +42,7 @@ class AttendanceQueryService
$sectionCodes = array_keys($bySection);
$labels = [];
if (!empty($sectionCodes)) {
if (! empty($sectionCodes)) {
$rows = $this->classSection
->query()
->select(['class_section_id', 'class_section_name'])
@@ -52,13 +52,13 @@ class AttendanceQueryService
->toArray();
foreach ($rows as $row) {
$code = (int)$row['class_section_id'];
$name = trim((string)($row['class_section_name'] ?? ''));
$labels[$code] = $name !== '' ? $name : 'Section #' . $code;
$code = (int) $row['class_section_id'];
$name = trim((string) ($row['class_section_name'] ?? ''));
$labels[$code] = $name !== '' ? $name : 'Section #'.$code;
}
foreach ($sectionCodes as $code) {
$labels[$code] ??= 'Section #' . $code;
$labels[$code] ??= 'Section #'.$code;
}
}
@@ -67,10 +67,10 @@ class AttendanceQueryService
if ($sectionCode > 0) {
$assigned = $this->teacherClass->assignedForSectionTerm($sectionCode, $semester, $schoolYear);
$teacherIds = array_map(fn($r) => (int)$r['teacher_id'], $assigned);
$teacherIds = array_map(fn ($r) => (int) $r['teacher_id'], $assigned);
$statusMap = [];
if (!empty($teacherIds)) {
if (! empty($teacherIds)) {
$rows = DB::table('staff_attendance as sa')
->select('sa.user_id', 'sa.status', 'sa.reason')
->where('sa.semester', $semester)
@@ -80,7 +80,7 @@ class AttendanceQueryService
->get();
foreach ($rows as $row) {
$statusMap[(int)$row->user_id] = [
$statusMap[(int) $row->user_id] = [
'status' => $row->status,
'reason' => $row->reason,
];
@@ -88,15 +88,15 @@ class AttendanceQueryService
}
foreach ($assigned as $teacher) {
$teacherId = (int)$teacher['teacher_id'];
$position = strtolower((string)($teacher['position'] ?? 'main'));
$teacherId = (int) $teacher['teacher_id'];
$position = strtolower((string) ($teacher['position'] ?? 'main'));
$position = in_array($position, ['main', 'ta'], true) ? $position : 'main';
$name = trim(($teacher['firstname'] ?? '') . ' ' . ($teacher['lastname'] ?? ''));
$name = trim(($teacher['firstname'] ?? '').' '.($teacher['lastname'] ?? ''));
$cell = $statusMap[$teacherId] ?? ['status' => null, 'reason' => null];
$grid[] = [
'teacher_id' => $teacherId,
'name' => $name !== '' ? $name : 'User#' . $teacherId,
'name' => $name !== '' ? $name : 'User#'.$teacherId,
'position' => $position,
'status' => $cell['status'],
'reason' => $cell['reason'],
@@ -125,13 +125,13 @@ class AttendanceQueryService
public function teacherAttendanceFormData(?int $userId, int $requestedSectionId = 0): array
{
if (!$userId) {
if (! $userId) {
throw new RuntimeException('User not logged in.');
}
$teacher = $this->user->find($userId);
$teacherName = $teacher
? trim(($teacher->firstname ?? '') . ' ' . ($teacher->lastname ?? ''))
? trim(($teacher->firstname ?? '').' '.($teacher->lastname ?? ''))
: 'Unknown Teacher';
$semester = $this->attendanceService->currentSemester();
@@ -145,8 +145,8 @@ class AttendanceQueryService
$activeSection = null;
foreach ($assignments as $assignment) {
$cid = (int)($assignment['class_section_id'] ?? 0);
$pk = (int)($assignment['class_section_pk'] ?? 0);
$cid = (int) ($assignment['class_section_id'] ?? 0);
$pk = (int) ($assignment['class_section_pk'] ?? 0);
if ($requestedSectionId > 0 && ($requestedSectionId === $cid || $requestedSectionId === $pk)) {
$activeSection = $assignment;
@@ -156,8 +156,8 @@ class AttendanceQueryService
$activeSection ??= $assignments[0];
$classSectionCode = (int)($activeSection['class_section_id'] ?? 0);
$classSectionPk = (int)($activeSection['class_section_pk'] ?? 0);
$classSectionCode = (int) ($activeSection['class_section_id'] ?? 0);
$classSectionPk = (int) ($activeSection['class_section_pk'] ?? 0);
$classSectionId = $classSectionCode > 0 ? $classSectionCode : $classSectionPk;
if ($classSectionId <= 0) {
@@ -183,11 +183,11 @@ class AttendanceQueryService
$lockedByStudent = [];
$attendanceTable = $this->attendanceData->getTable();
$dateInSundaysSql = 'DATE(`' . $attendanceTable . '`.`date`) IN (' .
implode(',', array_fill(0, count($sundayDates), '?')) . ')';
$dateInSundaysSql = 'DATE(`'.$attendanceTable.'`.`date`) IN ('.
implode(',', array_fill(0, count($sundayDates), '?')).')';
foreach ($students as $student) {
$studentId = (int)$student['id'];
$studentId = (int) $student['id'];
$rows = AttendanceData::query()
->select(['date', 'status', 'is_reported', 'reason', 'modified_by'])
@@ -202,7 +202,7 @@ class AttendanceQueryService
})
->whereRaw($dateInSundaysSql, $sundayDates)
->get()
->map(fn($row) => (array)$row)
->map(fn ($row) => (array) $row)
->all();
$rows = $this->attendanceService->normalizeAttendanceEntries($rows);
@@ -226,8 +226,8 @@ class AttendanceQueryService
$recentHistory = [];
foreach ($recentRows as $row) {
$recentHistory[] = [
'date' => substr((string)($row['date'] ?? ''), 0, 10),
'status' => strtolower((string)($row['status'] ?? '')),
'date' => substr((string) ($row['date'] ?? ''), 0, 10),
'status' => strtolower((string) ($row['status'] ?? '')),
];
}
@@ -253,7 +253,7 @@ class AttendanceQueryService
// missed rows (SQL/driver quirks), still show statuses that match the visible columns.
foreach ($recentRows as $row) {
$d = $this->calendarDateKey($row['date'] ?? null);
if ($d === '' || !in_array($d, $sundayDates, true)) {
if ($d === '' || ! in_array($d, $sundayDates, true)) {
continue;
}
$rowStatus = $row['status'] ?? null;
@@ -340,13 +340,13 @@ class AttendanceQueryService
$teacherRows = [];
if (!empty($assigned)) {
$teacherIds = array_map(static fn($r) => (int)$r['teacher_id'], $assigned);
if (! empty($assigned)) {
$teacherIds = array_map(static fn ($r) => (int) $r['teacher_id'], $assigned);
$statusMap = [];
if (!empty($teacherIds)) {
$staffDateInSql = 'DATE(`sa`.`date`) IN (' .
implode(',', array_fill(0, count($sundayDates), '?')) . ')';
if (! empty($teacherIds)) {
$staffDateInSql = 'DATE(`sa`.`date`) IN ('.
implode(',', array_fill(0, count($sundayDates), '?')).')';
$staffQ = DB::table('staff_attendance as sa')
->select('sa.user_id', 'sa.date', 'sa.status', 'sa.reason')
->where('sa.semester', $semester)
@@ -372,7 +372,7 @@ class AttendanceQueryService
if ($dk === '') {
continue;
}
$statusMap[(int)$row->user_id][$dk] = [
$statusMap[(int) $row->user_id][$dk] = [
'status' => $row->status,
'reason' => $row->reason,
];
@@ -380,10 +380,10 @@ class AttendanceQueryService
}
foreach ($assigned as $teacher) {
$teacherId = (int)$teacher['teacher_id'];
$position = strtolower((string)($teacher['position'] ?? 'main'));
$teacherId = (int) $teacher['teacher_id'];
$position = strtolower((string) ($teacher['position'] ?? 'main'));
$position = in_array($position, ['main', 'ta'], true) ? $position : 'main';
$name = trim(($teacher['firstname'] ?? '') . ' ' . ($teacher['lastname'] ?? ''));
$name = trim(($teacher['firstname'] ?? '').' '.($teacher['lastname'] ?? ''));
$history = [];
foreach ($sundayDates as $date) {
@@ -400,7 +400,7 @@ class AttendanceQueryService
$teacherRows[] = [
'teacher_id' => $teacherId,
'position' => $position,
'name' => $name !== '' ? $name : 'User#' . $teacherId,
'name' => $name !== '' ? $name : 'User#'.$teacherId,
'sunday_statuses' => $history,
'today' => $history[$currentSunday] ?? null,
'today_reason' => $todayReason,
@@ -410,8 +410,8 @@ class AttendanceQueryService
$noSchoolDays = [];
$calendarTable = $this->calendar->getTable();
$calDateInSql = 'DATE(`' . $calendarTable . '`.`date`) IN (' .
implode(',', array_fill(0, count($sundayDates), '?')) . ')';
$calDateInSql = 'DATE(`'.$calendarTable.'`.`date`) IN ('.
implode(',', array_fill(0, count($sundayDates), '?')).')';
$calendarRows = $this->calendar->query()
->where('no_school', 1)
->whereRaw($calDateInSql, $sundayDates)
@@ -438,9 +438,9 @@ class AttendanceQueryService
'class_section_id' => $classSectionId,
'sunday_dates' => $sundayDates,
'current_sunday' => $currentSunday,
'enable_attendance' => (int)$this->configuration->getConfig('enable_attendance'),
'can_edit' => ((int)$this->configuration->getConfig('enable_attendance') === 1),
'class_id' => (int)$this->classSection->getClassId($classSectionId),
'enable_attendance' => (int) $this->configuration->getConfig('enable_attendance'),
'can_edit' => ((int) $this->configuration->getConfig('enable_attendance') === 1),
'class_id' => (int) $this->classSection->getClassId($classSectionId),
'no_school_days' => $noSchoolDays,
'today' => $currentSunday,
'locked_by_student' => $lockedByStudent,
@@ -463,7 +463,7 @@ class AttendanceQueryService
->where('sc.school_year', $schoolYear)
->groupBy('classSection.id', 'classSection.class_id', 'classSection.class_section_id', 'classSection.class_section_name')
->get()
->map(fn($row) => $row->toArray())
->map(fn ($row) => $row->toArray())
->all();
};
@@ -492,32 +492,32 @@ class AttendanceQueryService
$sectionCounts = $this->studentClass->getStudentCountsBySection($effectiveTermYear);
foreach ($classSections as $classSection) {
$secPk = (int)($classSection['id'] ?? 0);
$secCodeRaw = (string)($classSection['class_section_id'] ?? '');
$secCode = $secCodeRaw !== '' ? $secCodeRaw : (string)$secPk;
$classId = (int)($classSection['class_id'] ?? 0);
$secPk = (int) ($classSection['id'] ?? 0);
$secCodeRaw = (string) ($classSection['class_section_id'] ?? '');
$secCode = $secCodeRaw !== '' ? $secCodeRaw : (string) $secPk;
$classId = (int) ($classSection['class_id'] ?? 0);
$studentsBySection[$secCode] = [];
$datesBySection[$secCode] = [];
$attendanceData[$secCode] = [];
$attendanceRecord[$secCode] = [];
$countForCode = (int)($sectionCounts[$secCode] ?? 0);
$countForPk = (int)($sectionCounts[$secPk] ?? 0);
$countForCode = (int) ($sectionCounts[$secCode] ?? 0);
$countForPk = (int) ($sectionCounts[$secPk] ?? 0);
$sectionHasStudents = ($countForCode + $countForPk) > 0;
$students = $this->studentClass->getClassStudents($secCode, $effectiveTermYear);
if (!$students && $secPk && (string)$secPk !== (string)$secCode) {
if (! $students && $secPk && (string) $secPk !== (string) $secCode) {
$students = $this->studentClass->getClassStudents($secPk, $effectiveTermYear);
}
if (!$sectionHasStudents || !$students) {
if (! $sectionHasStudents || ! $students) {
continue;
}
// Bulk-load student profiles for the whole section in one query
$studentsArray = is_array($students) ? $students : $students->toArray();
$studentIds = array_map(fn($sc) => (int)($sc['student_id'] ?? $sc->student_id ?? 0), $studentsArray);
$studentIds = array_map(fn ($sc) => (int) ($sc['student_id'] ?? $sc->student_id ?? 0), $studentsArray);
$studentProfiles = $this->student
->query()
->select(['id', 'firstname', 'lastname', 'school_id'])
@@ -525,12 +525,13 @@ class AttendanceQueryService
->where('is_active', 1)
->get()
->keyBy('id')
->map(fn($row) => $row->toArray())
->map(fn ($row) => $row->toArray())
->all();
$activeIds = array_keys($studentProfiles);
if (empty($activeIds)) {
unset($studentsBySection[$secCode], $datesBySection[$secCode], $attendanceData[$secCode], $attendanceRecord[$secCode]);
continue;
}
@@ -539,17 +540,17 @@ class AttendanceQueryService
->whereIn('student_id', $activeIds)
->where(function ($q) use ($secCode, $secPk) {
$q->where('class_section_id', $secCode);
if ($secPk && (string)$secPk !== (string)$secCode) {
if ($secPk && (string) $secPk !== (string) $secCode) {
$q->orWhere('class_section_id', $secPk);
}
})
->when($termSemester !== '', fn($q) => $q->where('semester', $termSemester))
->when($effectiveTermYear !== '', fn($q) => $q->where('school_year', $effectiveTermYear))
->when($termSemester !== '', fn ($q) => $q->where('semester', $termSemester))
->when($effectiveTermYear !== '', fn ($q) => $q->where('school_year', $effectiveTermYear))
->orderBy('date')
->get()
->map(fn($row) => $row->toArray())
->map(fn ($row) => $row->toArray())
->groupBy('student_id')
->map(fn($group) => $group->values()->all())
->map(fn ($group) => $group->values()->all())
->all();
// Bulk-load all attendance records (summaries) for the section in one query
@@ -557,36 +558,36 @@ class AttendanceQueryService
->whereIn('student_id', $activeIds)
->where(function ($q) use ($secCode, $secPk) {
$q->where('class_section_id', $secCode);
if ($secPk && (string)$secPk !== (string)$secCode) {
if ($secPk && (string) $secPk !== (string) $secCode) {
$q->orWhere('class_section_id', $secPk);
}
})
->when($termSemester !== '', fn($q) => $q->where('semester', $termSemester))
->when($effectiveTermYear !== '', fn($q) => $q->where('school_year', $effectiveTermYear))
->when($termSemester !== '', fn ($q) => $q->where('semester', $termSemester))
->when($effectiveTermYear !== '', fn ($q) => $q->where('school_year', $effectiveTermYear))
->get()
->keyBy('student_id')
->map(fn($row) => $row->toArray())
->map(fn ($row) => $row->toArray())
->all();
$hasRoster = false;
foreach ($studentIds as $studentId) {
$student = $studentProfiles[$studentId] ?? null;
if (!$student) {
if (! $student) {
continue;
}
$studentsBySection[$secCode][] = $student;
$studentSchoolMap[$studentId] = (string)($student['school_id'] ?? '');
$studentSchoolMap[$studentId] = (string) ($student['school_id'] ?? '');
$hasRoster = true;
$entries = $this->attendanceService->normalizeAttendanceEntries(
array_map(fn($r) => (array)$r, $allEntries[$studentId] ?? [])
array_map(fn ($r) => (array) $r, $allEntries[$studentId] ?? [])
);
$attendanceData[$secCode][$studentId] = $entries;
foreach ($entries as $entry) {
$d = (string)($entry['date'] ?? '');
$d = (string) ($entry['date'] ?? '');
if ($d !== '') {
$datesBySection[$secCode][$d] = true;
}
@@ -600,8 +601,9 @@ class AttendanceQueryService
];
}
if (!$hasRoster) {
if (! $hasRoster) {
unset($studentsBySection[$secCode], $datesBySection[$secCode], $attendanceData[$secCode], $attendanceRecord[$secCode]);
continue;
}
@@ -610,7 +612,7 @@ class AttendanceQueryService
foreach ($attendanceData as $secId => &$studentEntries) {
foreach ($studentEntries as &$entries) {
usort($entries, static fn($a, $b) => strcmp((string)($a['date'] ?? ''), (string)($b['date'] ?? '')));
usort($entries, static fn ($a, $b) => strcmp((string) ($a['date'] ?? ''), (string) ($b['date'] ?? '')));
}
}
unset($studentEntries, $entries);
@@ -644,9 +646,9 @@ class AttendanceQueryService
->toArray();
foreach ($events as $event) {
$d = substr((string)($event['date'] ?? ''), 0, 10);
$d = substr((string) ($event['date'] ?? ''), 0, 10);
if ($d !== '') {
$noSchoolDays[$d] = trim((string)($event['title'] ?? 'No School')) ?: 'No School';
$noSchoolDays[$d] = trim((string) ($event['title'] ?? 'No School')) ?: 'No School';
}
}
@@ -668,12 +670,12 @@ class AttendanceQueryService
foreach ($studentEntries as $studentId => $entries) {
$statusByDate = [];
foreach ($entries as $entry) {
$d = substr((string)($entry['date'] ?? ''), 0, 10);
$d = substr((string) ($entry['date'] ?? ''), 0, 10);
if ($d === '' || empty($passedDatesSet[$d])) {
continue;
}
$st = strtolower(trim((string)($entry['status'] ?? '')));
if (!in_array($st, ['present', 'absent', 'late'], true)) {
$st = strtolower(trim((string) ($entry['status'] ?? '')));
if (! in_array($st, ['present', 'absent', 'late'], true)) {
continue;
}
$statusByDate[$d] = $st;
@@ -695,9 +697,9 @@ class AttendanceQueryService
$sum = $p + $l + $a;
$record = $attendanceRecord[$secCode][$studentId] ?? [];
$storedSum = (int)($record['total_presence'] ?? 0)
+ (int)($record['total_late'] ?? 0)
+ (int)($record['total_absence'] ?? 0);
$storedSum = (int) ($record['total_presence'] ?? 0)
+ (int) ($record['total_late'] ?? 0)
+ (int) ($record['total_absence'] ?? 0);
if ($storedSum !== $totalPassedDays && $storedSum !== $sum) {
DB::table('attendance_record')
@@ -733,7 +735,7 @@ class AttendanceQueryService
if (auth()->id()) {
$u = $this->user->query()->select('firstname', 'lastname')->find(auth()->id());
if ($u) {
$adminName = trim(($u->firstname ?? '') . ' ' . ($u->lastname ?? ''));
$adminName = trim(($u->firstname ?? '').' '.($u->lastname ?? ''));
}
}
@@ -773,8 +775,8 @@ class AttendanceQueryService
return [];
}
$staffDateInSql = 'DATE(`sa`.`date`) IN (' .
implode(',', array_fill(0, count($sundayDates), '?')) . ')';
$staffDateInSql = 'DATE(`sa`.`date`) IN ('.
implode(',', array_fill(0, count($sundayDates), '?')).')';
$run = static function (
bool $requireTcSemester,
@@ -830,8 +832,8 @@ class AttendanceQueryService
return [];
}
$staffDateInSql = 'DATE(`sa`.`date`) IN (' .
implode(',', array_fill(0, count($sundayDates), '?')) . ')';
$staffDateInSql = 'DATE(`sa`.`date`) IN ('.
implode(',', array_fill(0, count($sundayDates), '?')).')';
$ids = [];
@@ -905,7 +907,7 @@ class AttendanceQueryService
*/
private function calendarDateKey(mixed $value): string
{
$s = trim((string)($value ?? ''));
$s = trim((string) ($value ?? ''));
if ($s === '') {
return '';
}
@@ -25,16 +25,16 @@ class AttendanceRecordSyncService
->where('school_year', $schoolYear)
->first();
if (!$record) {
if (! $record) {
return;
}
$newStatus = strtolower($newStatus);
$oldStatus = strtolower((string)$oldStatus);
$oldStatus = strtolower((string) $oldStatus);
$presence = (int)($record->total_presence ?? 0);
$absence = (int)($record->total_absence ?? 0);
$late = (int)($record->total_late ?? 0);
$presence = (int) ($record->total_presence ?? 0);
$absence = (int) ($record->total_absence ?? 0);
$late = (int) ($record->total_late ?? 0);
if ($oldStatus === 'present') {
$presence--;
@@ -80,13 +80,14 @@ class AttendanceRecordSyncService
if ($record) {
$record->update([
'total_presence' => (int)($record->total_presence ?? 0) + ($status === 'present' ? 1 : 0),
'total_absence' => (int)($record->total_absence ?? 0) + ($status === 'absent' ? 1 : 0),
'total_late' => (int)($record->total_late ?? 0) + ($status === 'late' ? 1 : 0),
'total_attendance' => (int)($record->total_attendance ?? 0) + 1,
'total_presence' => (int) ($record->total_presence ?? 0) + ($status === 'present' ? 1 : 0),
'total_absence' => (int) ($record->total_absence ?? 0) + ($status === 'absent' ? 1 : 0),
'total_late' => (int) ($record->total_late ?? 0) + ($status === 'late' ? 1 : 0),
'total_attendance' => (int) ($record->total_attendance ?? 0) + 1,
'updated_at' => now(),
'modified_by' => $modifiedBy,
]);
return;
}
@@ -141,13 +142,13 @@ class AttendanceRecordSyncService
return $record->update($payload);
}
$payload['class_section_id'] = (int)$classSectionId;
$payload['class_section_id'] = (int) $classSectionId;
$payload['student_id'] = $studentId;
$payload['school_id'] = $schoolId;
$payload['semester'] = $semester;
$payload['school_year'] = $schoolYear;
$payload['created_at'] = now();
return (bool)AttendanceRecord::query()->create($payload);
return (bool) AttendanceRecord::query()->create($payload);
}
}
}
+30 -27
View File
@@ -27,24 +27,24 @@ class AttendanceService
public function currentSemester(): string
{
return (string)($this->configuration->getConfig('semester') ?? 'Fall');
return (string) ($this->configuration->getConfig('semester') ?? 'Fall');
}
public function currentSchoolYear(): string
{
return (string)($this->configuration->getConfig('school_year') ?? now()->year . '-' . (now()->year + 1));
return (string) ($this->configuration->getConfig('school_year') ?? now()->year.'-'.(now()->year + 1));
}
public function updateAttendanceManagement(Authenticatable $user, array $data): array
{
$classSectionId = (int)$data['class_section_id'];
$studentId = (int)$data['student_id'];
$status = strtolower((string)$data['status']);
$date = (string)$data['date'];
$classSectionId = (int) $data['class_section_id'];
$studentId = (int) $data['student_id'];
$status = strtolower((string) $data['status']);
$date = (string) $data['date'];
$reason = $data['reason'] ?? null;
$classId = $data['class_id'] ?? null;
$semester = (string)($data['semester'] ?? $this->currentSemester());
$schoolYear = (string)($data['school_year'] ?? $this->currentSchoolYear());
$semester = (string) ($data['semester'] ?? $this->currentSemester());
$schoolYear = (string) ($data['school_year'] ?? $this->currentSchoolYear());
$dayRow = AttendanceDay::query()
->where('class_section_id', $classSectionId)
@@ -67,11 +67,11 @@ class AttendanceService
'permissions' => method_exists($user, 'permissions') ? $user->permissions->pluck('name')->all() : [],
];
if (!$this->attendancePolicyService->canEditDay($dayPolicyRow, $currentUser)) {
if (! $this->attendancePolicyService->canEditDay($dayPolicyRow, $currentUser)) {
throw new RuntimeException('Attendance is locked for your role.');
}
$reportedRaw = strtolower((string)($data['is_reported'] ?? ''));
$reportedRaw = strtolower((string) ($data['is_reported'] ?? ''));
$isReported = $status === 'present'
? 'no'
: (in_array($reportedRaw, ['1', 'yes', 'y', 'true', 'on'], true) ? 'yes' : 'no');
@@ -98,7 +98,7 @@ class AttendanceService
'semester' => $semester,
'school_year' => $schoolYear,
'date' => $date,
'class_id' => (int)$classId,
'class_id' => (int) $classId,
'user_id' => $user->id,
]);
@@ -136,13 +136,13 @@ class AttendanceService
public function adminAddEntry(Authenticatable $user, array $data): array
{
$classSectionId = (int)$data['class_section_id'];
$studentId = (int)$data['student_id'];
$status = strtolower((string)$data['status']);
$date = (string)($data['date'] ?? now()->toDateString());
$classSectionId = (int) $data['class_section_id'];
$studentId = (int) $data['student_id'];
$status = strtolower((string) $data['status']);
$date = (string) ($data['date'] ?? now()->toDateString());
$reason = $data['reason'] ?? null;
$isReported = in_array(strtolower((string)($data['is_reported'] ?? 'no')), ['yes', 'no'], true)
? strtolower((string)($data['is_reported'] ?? 'no'))
$isReported = in_array(strtolower((string) ($data['is_reported'] ?? 'no')), ['yes', 'no'], true)
? strtolower((string) ($data['is_reported'] ?? 'no'))
: 'no';
$section = $this->classSection
@@ -152,7 +152,7 @@ class AttendanceService
->orWhere('class_section_id', $classSectionId)
->first();
$resolvedClassId = (int)($section->class_id ?? 0);
$resolvedClassId = (int) ($section->class_id ?? 0);
if ($resolvedClassId <= 0) {
throw new RuntimeException('Cannot resolve class_id for this section.');
@@ -210,29 +210,32 @@ class AttendanceService
$reportedRaw = $row['is_reported'] ?? ($row['reported'] ?? '');
$row['is_reported'] = $this->normalizeReportedFlag($reportedRaw);
}
return $entries;
}
public function normalizeStatus(?string $status): string
{
$status = strtolower(trim((string)$status));
$status = strtolower(trim((string) $status));
return in_array($status, ['present', 'absent', 'late'], true) ? $status : $status;
}
public function normalizeReportedFlag(mixed $flag): string
{
$v = strtolower(trim((string)$flag));
$v = strtolower(trim((string) $flag));
return in_array($v, ['yes', '1', 'true', 'y', 'on'], true) ? 'yes' : 'no';
}
public function detectExternalSubmission(?array $row): array
{
if (empty($row) || !is_array($row)) {
if (empty($row) || ! is_array($row)) {
return ['locked' => false, 'source' => null];
}
$reportedRaw = strtolower((string)($row['is_reported'] ?? ''));
$reason = strtolower((string)($row['reason'] ?? ''));
$reportedRaw = strtolower((string) ($row['is_reported'] ?? ''));
$reason = strtolower((string) ($row['reason'] ?? ''));
$isParent = in_array($reportedRaw, ['yes', '1', 'true', 'y'], true)
|| str_contains($reason, 'parent-reported')
@@ -242,7 +245,7 @@ class AttendanceService
return ['locked' => true, 'source' => 'parent'];
}
$modifierId = (int)($row['modified_by'] ?? 0);
$modifierId = (int) ($row['modified_by'] ?? 0);
if ($modifierId > 0 && $this->isAdminLikeUserId($modifierId)) {
return ['locked' => true, 'source' => 'admin'];
}
@@ -264,12 +267,12 @@ class AttendanceService
$excluded = ['parent', 'guest', 'teacher', 'teacher_assistant', 'assistant_teacher', 'ta'];
foreach ($roles as $role) {
$name = strtolower(str_replace([' ', '-'], '_', (string)($role['role_name'] ?? '')));
if ($name !== '' && !in_array($name, $excluded, true)) {
$name = strtolower(str_replace([' ', '-'], '_', (string) ($role['role_name'] ?? '')));
if ($name !== '' && ! in_array($name, $excluded, true)) {
return true;
}
}
return false;
}
}
}
@@ -29,8 +29,8 @@ class AttendanceSummaryRebuildService
$semester = (string) ($row['semester'] ?? '');
$status = strtolower((string) ($row['status'] ?? ''));
$key = $studentId . '-' . $schoolYear . '-' . $semester;
if (!isset($summary[$key])) {
$key = $studentId.'-'.$schoolYear.'-'.$semester;
if (! isset($summary[$key])) {
$summary[$key] = [
'student_id' => $studentId,
'school_year' => $schoolYear,
@@ -11,16 +11,16 @@ class LateSlipLogQueryService
{
$query = LateSlipLog::query();
if (!empty($filters['school_year'])) {
if (! empty($filters['school_year'])) {
$query->where('school_year', (string) $filters['school_year']);
}
if (!empty($filters['semester'])) {
if (! empty($filters['semester'])) {
$query->where('semester', (string) $filters['semester']);
}
if (!empty($filters['q'])) {
$query->where('student_name', 'like', '%' . $filters['q'] . '%');
if (! empty($filters['q'])) {
$query->where('student_name', 'like', '%'.$filters['q'].'%');
}
$dateFrom = $this->toDbDate($filters['date_from'] ?? null);
@@ -58,6 +58,7 @@ class LateSlipLogQueryService
return null;
}
$ts = strtotime($value);
return $ts ? date('Y-m-d', $ts) : null;
}
}
@@ -9,7 +9,7 @@ class SemesterRangeService
{
public function normalizeSemester(?string $semester): string
{
$value = strtolower(trim((string)$semester));
$value = strtolower(trim((string) $semester));
return match ($value) {
'fall', 'autumn' => 'Fall',
@@ -76,7 +76,7 @@ class SemesterRangeService
protected function parseSchoolYear(string $schoolYear): array
{
if (preg_match('/^\s*(\d{4})\s*-\s*(\d{4})\s*$/', $schoolYear, $m)) {
return [(int)$m[1], (int)$m[2]];
return [(int) $m[1], (int) $m[2]];
}
$configured = trim((string) Configuration::getConfig('school_year'));
@@ -85,7 +85,7 @@ class SemesterRangeService
}
$year = (int) date('Y');
$derived = $year . '-' . ($year + 1);
$derived = $year.'-'.($year + 1);
Configuration::setConfigValueByKey('school_year', $derived);
return [$year, $year + 1];
@@ -2,13 +2,14 @@
namespace App\Services\Attendance;
use App\Controllers\View\AttendanceController;
use App\Models\AttendanceDay;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\StaffAttendance;
use App\Models\TeacherClass;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\Authenticatable;
use App\Models\ClassSection;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;
@@ -23,7 +24,7 @@ class StaffAttendanceService
) {}
/**
* legacy {@see \App\Controllers\View\AttendanceController::index} — single date / section teacher grid JSON.
* legacy {@see AttendanceController::index} — single date / section teacher grid JSON.
*/
public function teacherAttendanceDayIndex(?string $semester, ?string $schoolYear, string $dateYmd, int $sectionCode): array
{
@@ -44,7 +45,7 @@ class StaffAttendanceService
->where('class_section_id', $code)
->value('class_section_name');
$name = trim((string) $name);
$labels[$code] = $name !== '' ? $name : ('Section #' . $code);
$labels[$code] = $name !== '' ? $name : ('Section #'.$code);
}
$grid = [];
@@ -76,7 +77,7 @@ class StaffAttendanceService
$tid = (int) ($t['teacher_id'] ?? 0);
$posRaw = strtolower((string) ($t['position'] ?? 'main'));
$pos = in_array($posRaw, ['main', 'ta'], true) ? $posRaw : 'main';
$name = trim(($t['firstname'] ?? '') . ' ' . ($t['lastname'] ?? '')) ?: ('User#' . $tid);
$name = trim(($t['firstname'] ?? '').' '.($t['lastname'] ?? '')) ?: ('User#'.$tid);
$cell = $statusMap[$tid] ?? ['status' => null, 'reason' => null];
@@ -108,7 +109,7 @@ class StaffAttendanceService
}
/**
* Bulk save for legacy {@see \App\Controllers\View\AttendanceController::save} (method missing in legacy; implemented here).
* Bulk save for legacy {@see AttendanceController::save} (method missing in legacy; implemented here).
*/
public function saveTeacherAttendanceBulk(Authenticatable $user, array $payload): array
{
@@ -181,7 +182,7 @@ class StaffAttendanceService
public function monthData(?string $semester, ?string $schoolYear): array
{
$semester = $semester ?: (string)$this->configuration->getConfig('semester');
$semester = $semester ?: (string) $this->configuration->getConfig('semester');
[
'school_year' => $schoolYear,
'current_year' => $currentYear,
@@ -232,7 +233,7 @@ class StaffAttendanceService
$sectionCodes = array_keys($assignedBySection);
$labels = [];
if (!empty($sectionCodes)) {
if (! empty($sectionCodes)) {
$rows = $this->classSection->query()
->select(['class_section_id', 'class_section_name'])
->whereIn('class_section_id', $sectionCodes)
@@ -240,20 +241,20 @@ class StaffAttendanceService
->toArray();
foreach ($rows as $row) {
$labels[(int)$row['class_section_id']] = trim((string)$row['class_section_name']) ?: 'Section #' . (int)$row['class_section_id'];
$labels[(int) $row['class_section_id']] = trim((string) $row['class_section_name']) ?: 'Section #'.(int) $row['class_section_id'];
}
}
$teacherIds = [];
foreach ($assignedBySection as $rows) {
foreach ($rows as $row) {
$teacherIds[(int)$row['teacher_id']] = true;
$teacherIds[(int) $row['teacher_id']] = true;
}
}
$teacherIds = array_keys($teacherIds);
$statusByTeacher = [];
if (!empty($teacherIds) && !empty($days)) {
if (! empty($teacherIds) && ! empty($days)) {
$query = DB::table('staff_attendance')
->select('user_id', 'date', 'status', 'reason')
->where('school_year', $schoolYear)
@@ -267,8 +268,8 @@ class StaffAttendanceService
$rows = $query->get();
foreach ($rows as $row) {
$statusByTeacher[(int)$row->user_id][(string)$row->date] = [
'status' => strtolower((string)$row->status),
$statusByTeacher[(int) $row->user_id][(string) $row->date] = [
'status' => strtolower((string) $row->status),
'reason' => $row->reason,
];
}
@@ -284,7 +285,7 @@ class StaffAttendanceService
$noSchoolDays = [];
foreach ($noSchoolRows as $row) {
$noSchoolDays[] = (string)$row->date;
$noSchoolDays[] = (string) $row->date;
}
$sections = [];
@@ -292,9 +293,9 @@ class StaffAttendanceService
$teachersPayload = [];
foreach (($assignedBySection[$code] ?? []) as $row) {
$teacherId = (int)$row['teacher_id'];
$name = trim(($row['firstname'] ?? '') . ' ' . ($row['lastname'] ?? '')) ?: ('User#' . $teacherId);
$position = strtolower((string)($row['position'] ?? 'main'));
$teacherId = (int) $row['teacher_id'];
$name = trim(($row['firstname'] ?? '').' '.($row['lastname'] ?? '')) ?: ('User#'.$teacherId);
$position = strtolower((string) ($row['position'] ?? 'main'));
$position = in_array($position, ['main', 'ta'], true) ? $position : 'main';
$cells = [];
@@ -302,7 +303,7 @@ class StaffAttendanceService
foreach ($days as $date) {
$cell = $statusByTeacher[$teacherId][$date] ?? null;
if (!$cell || empty($cell['status'])) {
if (! $cell || empty($cell['status'])) {
continue;
}
@@ -327,15 +328,15 @@ class StaffAttendanceService
}
$sections[] = [
'section_code' => (int)$code,
'label' => $labels[$code] ?? ('Section #' . (int)$code),
'section_code' => (int) $code,
'label' => $labels[$code] ?? ('Section #'.(int) $code),
'teachers' => $teachersPayload,
];
}
$adminStatusByUser = [];
$adminIds = [];
if (!empty($days)) {
if (! empty($days)) {
$query = DB::table('staff_attendance')
->select('user_id', 'date', 'status', 'reason')
->where('school_year', $schoolYear)
@@ -361,7 +362,7 @@ class StaffAttendanceService
$adminIds = array_keys($adminIds);
$admins = [];
if (!empty($adminIds)) {
if (! empty($adminIds)) {
$rolesRows = DB::table('user_roles as ur')
->select('ur.user_id', 'r.name as role_name', 'r.slug as role_slug', 'r.priority')
->join('roles as r', 'r.id', '=', 'ur.role_id')
@@ -389,20 +390,20 @@ class StaffAttendanceService
$namesByUser = [];
foreach ($userRows as $row) {
$namesByUser[(int) $row->id] = trim(((string) ($row->firstname ?? '')) . ' ' . ((string) ($row->lastname ?? '')));
$namesByUser[(int) $row->id] = trim(((string) ($row->firstname ?? '')).' '.((string) ($row->lastname ?? '')));
}
foreach ($adminIds as $uid) {
$picked = null;
foreach (($rolesByUser[$uid] ?? []) as $role) {
$slug = strtolower((string) ($role['role_slug'] ?? $role['role_name'] ?? ''));
if (!in_array($slug, $excludeSlugs, true)) {
if (! in_array($slug, $excludeSlugs, true)) {
$picked = $role;
break;
}
}
if (!$picked) {
if (! $picked) {
continue;
}
@@ -410,7 +411,7 @@ class StaffAttendanceService
$cells = [];
foreach ($days as $date) {
$cell = $adminStatusByUser[$uid][$date] ?? null;
if (!$cell || empty($cell['status'])) {
if (! $cell || empty($cell['status'])) {
continue;
}
$cells[$date] = $cell;
@@ -425,7 +426,7 @@ class StaffAttendanceService
$admins[] = [
'user_id' => $uid,
'name' => $namesByUser[$uid] !== '' ? $namesByUser[$uid] : ('User#' . $uid),
'name' => $namesByUser[$uid] !== '' ? $namesByUser[$uid] : ('User#'.$uid),
'role' => (string) ($picked['role_name'] ?? 'Admin'),
'cells' => $cells,
'totals' => $totals,
@@ -508,7 +509,7 @@ class StaffAttendanceService
}
}
if ($currentYear !== '' && !in_array($currentYear, $schoolYears, true)) {
if ($currentYear !== '' && ! in_array($currentYear, $schoolYears, true)) {
array_unshift($schoolYears, $currentYear);
}
@@ -523,7 +524,7 @@ class StaffAttendanceService
? $requestedSchoolYear
: ($currentYear !== '' ? $currentYear : ($schoolYears[0] ?? ''));
if ($resolvedYear !== '' && !in_array($resolvedYear, $schoolYears, true)) {
if ($resolvedYear !== '' && ! in_array($resolvedYear, $schoolYears, true)) {
array_unshift($schoolYears, $resolvedYear);
}
@@ -539,7 +540,7 @@ class StaffAttendanceService
protected function buildRangeLabel(string $schoolYear, string $semesterNorm, string $rangeStart, string $rangeEnd): string
{
if ($semesterNorm === '') {
return 'School Year ' . $schoolYear;
return 'School Year '.$schoolYear;
}
return sprintf(
@@ -553,14 +554,14 @@ class StaffAttendanceService
public function adminsAttendanceData(?string $date, ?string $semester, ?string $schoolYear): array
{
$date = $date ?: now()->toDateString();
$semester = $semester ?: (string)$this->configuration->getConfig('semester');
$schoolYear = $schoolYear ?: (string)$this->configuration->getConfig('school_year');
$semester = $semester ?: (string) $this->configuration->getConfig('semester');
$schoolYear = $schoolYear ?: (string) $this->configuration->getConfig('school_year');
$allStaff = $this->staffAttendance->staffWithStatusForDay($date, $semester, $schoolYear, []);
$userIds = [];
foreach ($allStaff as $row) {
$uid = (int)($row['user_id'] ?? 0);
$uid = (int) ($row['user_id'] ?? 0);
if ($uid > 0) {
$userIds[$uid] = true;
}
@@ -577,19 +578,19 @@ class StaffAttendanceService
$rolesByUser = [];
foreach ($rolesRows as $row) {
$rolesByUser[(int)$row->user_id][] = (array)$row;
$rolesByUser[(int) $row->user_id][] = (array) $row;
}
foreach ($rolesByUser as &$list) {
usort($list, fn($a, $b) => ((int)($a['priority'] ?? 100)) <=> ((int)($b['priority'] ?? 100)));
usort($list, fn ($a, $b) => ((int) ($a['priority'] ?? 100)) <=> ((int) ($b['priority'] ?? 100)));
}
$excludeSlugs = ['parent', 'guest', 'teacher', 'teacher_assistant', 'ta', 'assistant_teacher'];
$staffByUser = [];
foreach ($allStaff as $row) {
$uid = (int)($row['user_id'] ?? 0);
if ($uid > 0 && !isset($staffByUser[$uid])) {
$uid = (int) ($row['user_id'] ?? 0);
if ($uid > 0 && ! isset($staffByUser[$uid])) {
$staffByUser[$uid] = $row;
}
}
@@ -600,14 +601,14 @@ class StaffAttendanceService
$picked = null;
foreach ($roles as $role) {
$slug = strtolower((string)($role['role_slug'] ?? $role['role_name'] ?? ''));
if (!in_array($slug, $excludeSlugs, true)) {
$slug = strtolower((string) ($role['role_slug'] ?? $role['role_name'] ?? ''));
if (! in_array($slug, $excludeSlugs, true)) {
$picked = $role;
break;
}
}
if (!$picked) {
if (! $picked) {
continue;
}
@@ -618,8 +619,9 @@ class StaffAttendanceService
}
usort($adminsGrid, function ($a, $b) {
$an = trim(($a['firstname'] ?? '') . ' ' . ($a['lastname'] ?? ''));
$bn = trim(($b['firstname'] ?? '') . ' ' . ($b['lastname'] ?? ''));
$an = trim(($a['firstname'] ?? '').' '.($a['lastname'] ?? ''));
$bn = trim(($b['firstname'] ?? '').' '.($b['lastname'] ?? ''));
return strcasecmp($an, $bn);
});
@@ -633,20 +635,20 @@ class StaffAttendanceService
public function saveAdmins(Authenticatable $user, array $data): array
{
$date = (string)$data['date'];
$semester = (string)$data['semester'];
$schoolYear = (string)$data['school_year'];
$admins = (array)($data['admins'] ?? $data['staff'] ?? []);
$date = (string) $data['date'];
$semester = (string) $data['semester'];
$schoolYear = (string) $data['school_year'];
$admins = (array) ($data['admins'] ?? $data['staff'] ?? []);
$allowedStatuses = ['present', 'absent', 'late'];
$excludedRoleSlugs = ['parent', 'guest', 'teacher', 'teacher_assistant'];
DB::transaction(function () use ($admins, $date, $semester, $schoolYear, $allowedStatuses, $excludedRoleSlugs) {
foreach ($admins as $uid => $row) {
$uid = (int)$uid;
$status = strtolower(trim((string)($row['status'] ?? '')));
$reason = trim((string)($row['reason'] ?? ''));
$roleName = (string)($row['role_name'] ?? '');
$roleSlug = strtolower(str_replace(['-', ' '], '_', (string)($row['role_slug'] ?? $roleName)));
$uid = (int) $uid;
$status = strtolower(trim((string) ($row['status'] ?? '')));
$reason = trim((string) ($row['reason'] ?? ''));
$roleName = (string) ($row['role_name'] ?? '');
$roleSlug = strtolower(str_replace(['-', ' '], '_', (string) ($row['role_slug'] ?? $roleName)));
if (in_array($roleSlug, $excludedRoleSlugs, true)) {
continue;
@@ -659,10 +661,11 @@ class StaffAttendanceService
->where('semester', $semester)
->where('school_year', $schoolYear)
->delete();
continue;
}
if (!in_array($status, $allowedStatuses, true)) {
if (! in_array($status, $allowedStatuses, true)) {
continue;
}
@@ -692,13 +695,13 @@ class StaffAttendanceService
public function saveCell(Authenticatable $user, array $data): array
{
$date = (string)$data['date'];
$status = (string)($data['status'] ?? '');
$targetId = (int)$data['user_id'];
$roleName = trim((string)($data['role_name'] ?? ''));
$semester = (string)$data['semester'];
$schoolYear = (string)$data['school_year'];
$reason = trim((string)($data['reason'] ?? ''));
$date = (string) $data['date'];
$status = (string) ($data['status'] ?? '');
$targetId = (int) $data['user_id'];
$roleName = trim((string) ($data['role_name'] ?? ''));
$semester = (string) $data['semester'];
$schoolYear = (string) $data['school_year'];
$reason = trim((string) ($data['reason'] ?? ''));
if ($status === '') {
DB::table('staff_attendance')
@@ -732,9 +735,9 @@ class StaffAttendanceService
public function monthCsv(?string $semester, ?string $schoolYear, ?string $scope): StreamedResponse
{
$semester = $semester ?: (string)$this->configuration->getConfig('semester');
$schoolYear = $schoolYear ?: (string)$this->configuration->getConfig('school_year');
$scope = strtolower((string)$scope);
$semester = $semester ?: (string) $this->configuration->getConfig('semester');
$schoolYear = $schoolYear ?: (string) $this->configuration->getConfig('school_year');
$scope = strtolower((string) $scope);
[$rangeStart, $rangeEnd] = $this->semesterRangeService->getSchoolYearRange($schoolYear);
$semesterNorm = $this->semesterRangeService->normalizeSemester($semester);
@@ -748,9 +751,9 @@ class StaffAttendanceService
$daysList = $this->semesterRangeService->buildSundayList($rangeStart, $rangeEnd);
$filename = ($scope === 'admins' ? 'admin_attendance_' : 'teacher_attendance_')
. $semester . '_' . str_replace('/', '-', $schoolYear) . '.csv';
.$semester.'_'.str_replace('/', '-', $schoolYear).'.csv';
return response()->streamDownload(function () use ($semester, $schoolYear, $scope, $daysList, $semesterNorm, $rangeStart, $rangeEnd) {
return response()->streamDownload(function () use ($schoolYear, $scope, $semesterNorm, $rangeStart, $rangeEnd) {
$out = fopen('php://output', 'w');
if ($scope === 'admins') {
@@ -770,12 +773,13 @@ class StaffAttendanceService
fputcsv($out, [
$row->user_id,
$row->date,
strtoupper(substr((string)$row->status, 0, 1)),
strtoupper(substr((string) $row->status, 0, 1)),
$row->reason,
]);
}
fclose($out);
return;
}
@@ -795,7 +799,7 @@ class StaffAttendanceService
fputcsv($out, [
$row->user_id,
$row->date,
strtoupper(substr((string)$row->status, 0, 1)),
strtoupper(substr((string) $row->status, 0, 1)),
$row->reason,
]);
}
@@ -70,7 +70,7 @@ class StudentAttendanceWriterService
public function resolveStudentSchoolId(int $studentId, ?string $studentSchoolId = null): string
{
$studentSchoolId = trim((string)$studentSchoolId);
$studentSchoolId = trim((string) $studentSchoolId);
if ($studentSchoolId !== '') {
return $studentSchoolId;
@@ -78,25 +78,25 @@ class StudentAttendanceWriterService
$studentRow = $this->student->query()->select('school_id')->find($studentId);
if (!$studentRow || empty($studentRow->school_id)) {
if (! $studentRow || empty($studentRow->school_id)) {
throw new RuntimeException('Student school ID not found.');
}
return (string)$studentRow->school_id;
return (string) $studentRow->school_id;
}
public function saveOrUpdateStudentAttendance(array $payload): array
{
$classSectionId = (int)$payload['class_section_id'];
$studentId = (int)$payload['student_id'];
$classSectionId = (int) $payload['class_section_id'];
$studentId = (int) $payload['student_id'];
$studentSchoolId = $this->resolveStudentSchoolId($studentId, $payload['school_id'] ?? null);
$status = strtolower((string)$payload['status']);
$status = strtolower((string) $payload['status']);
$reason = $payload['reason'] ?? null;
$reported = $payload['is_reported'] ?? null;
$semester = (string)$payload['semester'];
$schoolYear = (string)$payload['school_year'];
$date = (string)$payload['date'];
$classId = (int)$payload['class_id'];
$semester = (string) $payload['semester'];
$schoolYear = (string) $payload['school_year'];
$date = (string) $payload['date'];
$classId = (int) $payload['class_id'];
$userId = $payload['user_id'] ?? null;
$existing = AttendanceData::query()
@@ -110,7 +110,7 @@ class StudentAttendanceWriterService
$oldStatus = $existing->status;
$this->updateAttendanceData(
(int)$existing->id,
(int) $existing->id,
$status,
$reason,
$reported,
@@ -131,7 +131,7 @@ class StudentAttendanceWriterService
return [
'mode' => 'updated',
'attendance_id' => (int)$existing->id,
'attendance_id' => (int) $existing->id,
'old_status' => $oldStatus,
'new_status' => $status,
'school_id' => $studentSchoolId,
@@ -172,10 +172,10 @@ class StudentAttendanceWriterService
return [
'mode' => 'created',
'attendance_id' => (int)($created->id ?? 0),
'attendance_id' => (int) ($created->id ?? 0),
'old_status' => null,
'new_status' => $status,
'school_id' => $studentSchoolId,
];
}
}
}
@@ -31,7 +31,7 @@ class TeacherAttendanceSubmissionService
callable $currentSemester,
callable $currentSchoolYear
): array {
$rawSection = trim((string)$data['class_section_id']);
$rawSection = trim((string) $data['class_section_id']);
if ($rawSection === '') {
throw new RuntimeException('Missing or invalid class section.');
@@ -42,36 +42,36 @@ class TeacherAttendanceSubmissionService
->where('class_section_id', $rawSection)
->first();
if (!$sectionRow && ctype_digit($rawSection)) {
if (! $sectionRow && ctype_digit($rawSection)) {
$sectionRow = DB::table('classSection')
->select('id', 'class_id', 'class_section_id')
->where('id', (int)$rawSection)
->where('id', (int) $rawSection)
->first();
}
if (!$sectionRow) {
if (! $sectionRow) {
throw new RuntimeException('Invalid class section.');
}
$classSectionId = (int)$sectionRow->class_section_id;
$classSectionPk = (int)($sectionRow->id ?? 0);
$classSectionId = (int) $sectionRow->class_section_id;
$classSectionPk = (int) ($sectionRow->id ?? 0);
$alsoSectionId = ($classSectionPk > 0 && $classSectionPk !== $classSectionId) ? $classSectionPk : null;
$classId = (int)$sectionRow->class_id;
$classId = (int) $sectionRow->class_id;
$attendanceData = $data['attendance'] ?? [];
$teachersData = $data['teachers'] ?? [];
if (empty($attendanceData) || !is_array($attendanceData)) {
if (empty($attendanceData) || ! is_array($attendanceData)) {
throw new RuntimeException('No student attendance data provided.');
}
if (empty($teachersData) || !is_array($teachersData)) {
if (empty($teachersData) || ! is_array($teachersData)) {
throw new RuntimeException('No teacher attendance data provided.');
}
$rawDate = $data['date'] ?? now()->toDateString();
$attendDate = Carbon::parse($rawDate)->toDateString();
$semester = (string)$currentSemester();
$schoolYear = (string)$currentSchoolYear();
$semester = (string) $currentSemester();
$schoolYear = (string) $currentSchoolYear();
$dayRow = AttendanceDay::query()
->where('class_section_id', $classSectionId)
@@ -94,7 +94,7 @@ class TeacherAttendanceSubmissionService
'school_year' => $schoolYear,
];
if (!$this->attendancePolicyService->canEditDay($dayPolicyRow, $currentUser)) {
if (! $this->attendancePolicyService->canEditDay($dayPolicyRow, $currentUser)) {
throw new RuntimeException('Attendance is locked for your role.');
}
@@ -107,7 +107,7 @@ class TeacherAttendanceSubmissionService
$existingByStudent = [];
foreach ($existingRows as $row) {
$existingByStudent[(int)$row->student_id] = $row->toArray();
$existingByStudent[(int) $row->student_id] = $row->toArray();
}
$allowedStatuses = ['present', 'absent', 'late'];
@@ -129,10 +129,10 @@ class TeacherAttendanceSubmissionService
}
foreach ($assignedTeachers as $teacher) {
$teacherId = (int)$teacher['teacher_id'];
$status = strtolower((string)($teachersData[$teacherId]['status'] ?? ''));
$teacherId = (int) $teacher['teacher_id'];
$status = strtolower((string) ($teachersData[$teacherId]['status'] ?? ''));
if (!in_array($status, $allowedStatuses, true)) {
if (! in_array($status, $allowedStatuses, true)) {
throw new RuntimeException('Please fill teacher attendance for all assigned teachers.');
}
}
@@ -168,13 +168,13 @@ class TeacherAttendanceSubmissionService
);
foreach ($assignedTeachers as $teacher) {
$teacherId = (int)$teacher['teacher_id'];
$position = strtolower((string)($teacher['position'] ?? 'main'));
$teacherId = (int) $teacher['teacher_id'];
$position = strtolower((string) ($teacher['position'] ?? 'main'));
$position = $position === 'ta' ? 'ta' : 'main';
$staffPayload = [
'role_name' => 'Teacher',
'status' => strtolower((string)($teachersData[$teacherId]['status'] ?? 'present')),
'status' => strtolower((string) ($teachersData[$teacherId]['status'] ?? 'present')),
'reason' => ($teachersData[$teacherId]['reason'] ?? null) ?: null,
'updated_at' => now(),
'created_at' => now(),
@@ -198,9 +198,9 @@ class TeacherAttendanceSubmissionService
}
foreach ($attendanceData as $row) {
$studentId = (int)($row['student_id'] ?? 0);
$status = strtolower(trim((string)($row['status'] ?? '')));
$reason = trim((string)($row['reason'] ?? ''));
$studentId = (int) ($row['student_id'] ?? 0);
$status = strtolower(trim((string) ($row['status'] ?? '')));
$reason = trim((string) ($row['reason'] ?? ''));
$existing = $existingByStudent[$studentId] ?? null;
if ($isTeacher && $existing) {