fetchTodaySummary('absent'); return $this->notifyParents($rows, 'absent'); } public function sendLatesSummary(): int { $rows = $this->fetchTodaySummary('late'); return $this->notifyParents($rows, 'late'); } private function fetchTodaySummary(string $type): array { $start = now()->startOfDay(); $endEx = now()->addDay()->startOfDay(); $query = DB::table('attendance_data as ad') ->join('students as s', 's.id', '=', 'ad.student_id') ->leftJoin('users as u', 'u.id', '=', 's.parent_id') ->select( 'ad.date', 's.id as student_id', 's.firstname as student_firstname', 's.lastname as student_lastname', 'u.id as parent_id', 'u.email as parent_email', 'u.firstname as parent_firstname', 'u.lastname as parent_lastname' ) ->where('ad.date', '>=', $start) ->where('ad.date', '<', $endEx); if ($type === 'absent') { $query->where(function ($w) { $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']) ->orWhereRaw("UPPER(TRIM(ad.status)) LIKE 'LATE%'"); }); } return $query->get()->map(fn ($row) => (array) $row)->all(); } private function notifyParents(array $rows, string $type): int { $sent = 0; foreach ($rows as $row) { $parentId = (int) ($row['parent_id'] ?? 0); if ($parentId <= 0) { continue; } $studentName = trim((string) ($row['student_firstname'] ?? '').' '.(string) ($row['student_lastname'] ?? '')); $date = substr((string) ($row['date'] ?? ''), 0, 10); $message = sprintf( 'Daily Attendance Update: %s was marked %s on %s.', $studentName !== '' ? $studentName : 'Your student', $type, $date ); $this->notifier->notifyUser($parentId, 'Daily Attendance Update', $message, ['in_app'], 'attendance', 'parent'); $email = (string) ($row['parent_email'] ?? ''); if ($email !== '') { $body = '

'.e($message).'

'; $this->emailService->send($email, 'Daily Attendance Update', $body, 'attendance'); } $sent++; } return $sent; } }