Files
alrahma_sunday_school_api/app/Services/Administrator/TeacherSubmissionNotificationService.php
T
2026-03-08 16:33:24 -04:00

161 lines
5.9 KiB
PHP

<?php
namespace App\Services\Administrator;
use App\Models\ClassSection;
use App\Models\TeacherSubmissionNotificationHistory;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class TeacherSubmissionNotificationService
{
public function __construct(
protected AdministratorSharedService $shared,
protected TeacherSubmissionSupportService $support
) {
}
public function send(Request $request, int $adminId): array
{
$notify = $request->input('notify');
if (!is_array($notify)) {
return [
'success' => false,
'message' => 'Select at least one teacher to notify.',
'status' => 422,
];
}
$missingItemsPayload = $request->input('missing_items', []);
$targets = $this->extractTargets($notify);
if (empty($targets)) {
return [
'success' => false,
'message' => 'Select at least one teacher to notify.',
'status' => 422,
];
}
$teacherIds = array_values(array_unique(array_column($targets, 'teacher_id')));
$classSectionIds = array_values(array_unique(array_column($targets, 'class_section_id')));
$classSections = ClassSection::query()
->select('class_section_id', 'class_section_name')
->whereIn('class_section_id', $classSectionIds)
->get()
->keyBy('class_section_id');
$teachers = User::query()
->select('id', 'firstname', 'lastname', 'email')
->whereIn('id', $teacherIds)
->get()
->keyBy('id');
$adminUser = User::find($adminId);
$adminName = trim(($adminUser->firstname ?? '') . ' ' . ($adminUser->lastname ?? '')) ?: 'Administrator';
$scoreUrl = url('/');
$sentCount = 0;
$failCount = 0;
foreach ($targets as $target) {
$classSectionId = (int) $target['class_section_id'];
$teacherId = (int) $target['teacher_id'];
$teacher = $teachers->get($teacherId);
$sectionName = $classSections->get($classSectionId)?->class_section_name ?? "Section {$classSectionId}";
$teacherName = trim(($teacher->firstname ?? '') . ' ' . ($teacher->lastname ?? '')) ?: 'Teacher';
$missingPayload = $missingItemsPayload[$classSectionId][$teacherId] ?? '';
$missingItems = $this->support->parseMissingItemsPayload((string) $missingPayload);
$missingNote = !empty($missingItems)
? '<p>Outstanding items: ' . e($this->support->formatMissingItemsText($missingItems)) . '.</p>'
: '<p>Our records show no outstanding submissions for this section, but please verify if anything still needs attention.</p>';
$subject = "Reminder: Complete submissions for {$sectionName}";
$body = "<p>Dear {$teacherName},</p>"
. "<p>Administration is gently reminding you to wrap up any remaining score submissions and/or comments for {$sectionName}.</p>"
. $missingNote
. "<p>Visit <a href=\"{$scoreUrl}\">Teacher Score Submission</a> to address any remaining items.</p>"
. "<p>Thank you,<br>{$adminName}</p>";
$email = $teacher->email ?? '';
$status = 'failed';
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
try {
Mail::html($body, function ($message) use ($email, $subject) {
$message->to($email)->subject($subject);
});
$status = 'sent';
} catch (\Throwable $e) {
Log::error('Teacher submission notification failed: ' . $e->getMessage());
}
}
if ($status === 'sent') {
$sentCount++;
} else {
$failCount++;
}
TeacherSubmissionNotificationHistory::create([
'teacher_id' => $teacherId,
'class_section_id' => $classSectionId,
'admin_id' => $adminId,
'notification_category' => 'teacher_submissions',
'message' => $this->support->truncateNotificationMessage($body),
'status' => $status,
'school_year' => $this->shared->getSchoolYear(),
'semester' => $this->shared->getSemester(),
'sent_at' => now(),
]);
}
$parts = [];
if ($sentCount > 0) {
$parts[] = $sentCount . ' reminder' . ($sentCount === 1 ? '' : 's') . ' sent';
}
if ($failCount > 0) {
$parts[] = $failCount . ' reminder' . ($failCount === 1 ? '' : 's') . ' failed';
}
return [
'success' => $failCount === 0,
'message' => !empty($parts) ? implode(' and ', $parts) : 'No notifications were sent.',
'sent' => $sentCount,
'failed' => $failCount,
'status' => $failCount === 0 ? 200 : 207,
];
}
protected function extractTargets(array $notify): array
{
$targets = [];
foreach ($notify as $sectionIdRaw => $teachers) {
$sectionId = (int) $sectionIdRaw;
if ($sectionId <= 0 || !is_array($teachers)) {
continue;
}
foreach ($teachers as $teacherIdRaw => $value) {
$teacherId = (int) $teacherIdRaw;
if ($teacherId <= 0 || $value === null || $value === '') {
continue;
}
$targets["{$sectionId}_{$teacherId}"] = [
'class_section_id' => $sectionId,
'teacher_id' => $teacherId,
];
}
}
return array_values($targets);
}
}