reconstruction of the project
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user