e0dfc3ec82
API CI/CD / Validate (composer + pint) (push) Successful in 3m15s
API CI/CD / Test (PHPUnit) (push) Failing after 5m4s
API CI/CD / Build frontend assets (push) Successful in 1m3s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
97 lines
3.0 KiB
PHP
97 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Attendance;
|
|
|
|
use App\Services\EmailService;
|
|
use App\Services\Notifications\UserNotificationDispatchService;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
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');
|
|
}
|
|
|
|
private function fetchTodaySummary(string $type): array
|
|
{
|
|
$today = now()->toDateString();
|
|
|
|
$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'
|
|
)
|
|
->whereDate('ad.date', $today);
|
|
|
|
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 = '<p>'.e($message).'</p>';
|
|
$this->emailService->send($email, 'Daily Attendance Update', $body, 'attendance');
|
|
}
|
|
|
|
$sent++;
|
|
}
|
|
|
|
return $sent;
|
|
}
|
|
}
|