Fix Pint formatting
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user