419 lines
15 KiB
PHP
419 lines
15 KiB
PHP
<?php
|
|
|
|
namespace App\Services\School;
|
|
|
|
use App\Services\ApplicationUrlService;
|
|
use App\Services\EmailService;
|
|
use App\Services\Notifications\UserNotificationDispatchService;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class EnrollmentEventService
|
|
{
|
|
public function __construct(
|
|
private EmailService $emailService,
|
|
private UserNotificationDispatchService $notifier,
|
|
private ApplicationUrlService $urls,
|
|
) {
|
|
}
|
|
|
|
public function admissionUnderReview(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Admission Application Under Review',
|
|
];
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Admission Under Review',
|
|
'Your admission application is under review. We will notify you once it is approved.',
|
|
'registration'
|
|
);
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Admission Application Under Review',
|
|
$this->renderEmail('emails/status_admission_review', $emailData, 'Admission Application Under Review'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function paymentPending(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameSentence($students, $parentData['student_name'] ?? 'your student');
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'amountDue' => $parentData['amount'] ?? '',
|
|
'dueDate' => $parentData['due_date'] ?? '',
|
|
'portalLink' => $parentData['paymentLink'] ?? ($parentData['portalLink'] ?? $this->urls->webLoginUrl()),
|
|
'title' => 'Admission Decision',
|
|
];
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Payment Pending',
|
|
'Your payment is pending. Please check your email for details.',
|
|
'payment'
|
|
);
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Admission Decision',
|
|
$this->renderEmail('emails/status_payment_pending', $emailData, 'Admission Decision'),
|
|
'payment'
|
|
);
|
|
}
|
|
|
|
public function studentEnrolled(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentsDetails = $this->studentDetails($students);
|
|
$studentNameData = $this->studentNameData($students, $parentData);
|
|
$first = $studentsDetails[0] ?? [];
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $parentData['student_name'] ?? $studentNameData,
|
|
'schoolYear' => $parentData['school_year'] ?? date('Y'),
|
|
'studentId' => $parentData['student_id'] ?? ($first['studentId'] ?? ''),
|
|
'gradeLevel' => $parentData['grade_level'] ?? ($first['gradeLevel'] ?? ''),
|
|
'teacherName' => $parentData['teacher_name'] ?? ($first['teacherName'] ?? ''),
|
|
'startDate' => $parentData['start_date'] ?? ($first['startDate'] ?? ''),
|
|
'students' => count($studentsDetails) > 1 ? $studentsDetails : null,
|
|
'portalLink' => $this->urls->webLoginUrl(),
|
|
'title' => 'Enrollment Confirmation',
|
|
];
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Enrollment Confirmed',
|
|
'Enrollment confirmed. Please check your email for details.',
|
|
'registration'
|
|
);
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Enrollment Confirmation',
|
|
$this->renderEmail('emails/status_enrolled', $emailData, 'Enrollment Confirmation'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function withdrawUnderReview(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Withdrawal Request Received',
|
|
'Your withdrawal request is under review. Please check your email for details.',
|
|
'registration'
|
|
);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $parentData['student_name'] ?? $studentName,
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Withdrawal Under Review',
|
|
];
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Withdrawal Request Under Review',
|
|
$this->renderEmail('emails/status_withdraw_review', $emailData, 'Withdrawal Request Under Review'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function refundPending(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Refund Pending',
|
|
'A refund is being processed. Please check your email for details.',
|
|
'payment'
|
|
);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'refundAmount' => $parentData['amount'] ?? '',
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Refund Pending',
|
|
];
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Refund Pending',
|
|
$this->renderEmail('emails/status_refund_pending', $emailData, 'Refund Pending'),
|
|
'payment'
|
|
);
|
|
}
|
|
|
|
public function withdrawn(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
$withdrawals = $this->withdrawalsList($students);
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Withdrawal Confirmed',
|
|
'Your withdrawal has been completed. Please check your email for details.',
|
|
'registration'
|
|
);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'withdrawalDate' => $parentData['withdrawal_date'] ?? ($parentData['date'] ?? ''),
|
|
'withdrawals' => !empty($withdrawals) ? $withdrawals : null,
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Withdrawal Confirmed',
|
|
];
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Withdrawal Confirmed',
|
|
$this->renderEmail('emails/status_withdrawn', $emailData, 'Withdrawal Confirmed'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function denied(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
$studentsWithReasons = $this->studentsWithReasons($students);
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Admission Decision',
|
|
'We\'ve emailed you an update regarding your admission decision.',
|
|
'registration'
|
|
);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'students' => $studentsWithReasons ?: null,
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Admission Decision',
|
|
];
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Admission Decision',
|
|
$this->renderEmail('emails/status_denied', $emailData, 'Admission Decision'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function waitlist(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
$studentName = $this->studentNameData($students, $parentData);
|
|
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Waitlist Update',
|
|
'Your application is currently on the waitlist. Please check your email for details.',
|
|
'registration'
|
|
);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'studentName' => $studentName,
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Waitlist Update',
|
|
];
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Admission Decision',
|
|
$this->renderEmail('emails/status_waitlist', $emailData, 'Admission Decision'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
public function enrollmentStatusChanged(array $parentData, array $students): array
|
|
{
|
|
$parentName = $this->parentName($parentData);
|
|
|
|
$emailData = [
|
|
'parentName' => $parentName,
|
|
'schoolYear' => $parentData['school_year'] ?? '',
|
|
'changes' => $parentData['changes'] ?? [],
|
|
'portalLink' => $parentData['portalLink'] ?? $this->urls->webLoginUrl(),
|
|
'title' => 'Enrollment Status Update',
|
|
];
|
|
|
|
$summaryCount = count($emailData['changes']);
|
|
$this->notifyParent(
|
|
(int) ($parentData['user_id'] ?? 0),
|
|
'Enrollment Status Updated',
|
|
"Enrollment status updated for {$summaryCount} student(s). Check your email for details.",
|
|
'registration'
|
|
);
|
|
|
|
return $this->sendEmail(
|
|
(string) ($parentData['email'] ?? ''),
|
|
'Enrollment Status Update',
|
|
$this->renderEmail('emails/status_enrollment_batch', $emailData, 'Enrollment Status Update'),
|
|
'registration'
|
|
);
|
|
}
|
|
|
|
private function parentName(array $parentData): string
|
|
{
|
|
return trim((string) ($parentData['firstname'] ?? '') . ' ' . (string) ($parentData['lastname'] ?? ''));
|
|
}
|
|
|
|
private function studentNameData(array $studentdata, array $parentData)
|
|
{
|
|
$names = [];
|
|
foreach ($studentdata as $s) {
|
|
$nm = !empty($s['name'])
|
|
? trim((string) $s['name'])
|
|
: trim((string) ($s['firstname'] ?? '') . ' ' . (string) ($s['lastname'] ?? ''));
|
|
if ($nm !== '') {
|
|
$names[] = $nm;
|
|
}
|
|
}
|
|
|
|
if (empty($names)) {
|
|
return $parentData['student_name'] ?? 'your student';
|
|
}
|
|
if (count($names) === 1) {
|
|
return $names[0];
|
|
}
|
|
return $names;
|
|
}
|
|
|
|
private function studentNameSentence(array $studentdata, string $fallback): string
|
|
{
|
|
$names = [];
|
|
foreach ($studentdata as $s) {
|
|
$nm = !empty($s['name'])
|
|
? trim((string) $s['name'])
|
|
: trim((string) ($s['firstname'] ?? '') . ' ' . (string) ($s['lastname'] ?? ''));
|
|
if ($nm !== '') {
|
|
$names[] = $nm;
|
|
}
|
|
}
|
|
|
|
if (count($names) === 0) {
|
|
return $fallback;
|
|
}
|
|
if (count($names) === 1) {
|
|
return $names[0];
|
|
}
|
|
if (count($names) === 2) {
|
|
return $names[0] . ' and ' . $names[1];
|
|
}
|
|
$last = array_pop($names);
|
|
return implode(', ', $names) . ', and ' . $last;
|
|
}
|
|
|
|
private function studentDetails(array $studentdata): array
|
|
{
|
|
$details = [];
|
|
foreach ($studentdata as $s) {
|
|
$nm = !empty($s['name'])
|
|
? trim((string) $s['name'])
|
|
: trim((string) ($s['firstname'] ?? '') . ' ' . (string) ($s['lastname'] ?? ''));
|
|
if ($nm === '') {
|
|
continue;
|
|
}
|
|
$details[] = [
|
|
'name' => $nm,
|
|
'studentId' => $s['student_id'] ?? $s['id'] ?? '',
|
|
'gradeLevel' => $s['grade_level'] ?? $s['grade'] ?? '',
|
|
'teacherName' => $s['teacher_name'] ?? $s['teacher'] ?? '',
|
|
'startDate' => $s['start_date'] ?? '',
|
|
];
|
|
}
|
|
return $details;
|
|
}
|
|
|
|
private function withdrawalsList(array $studentdata): array
|
|
{
|
|
$withdrawals = [];
|
|
foreach ($studentdata as $s) {
|
|
$nm = !empty($s['name'])
|
|
? trim((string) $s['name'])
|
|
: trim((string) ($s['firstname'] ?? '') . ' ' . (string) ($s['lastname'] ?? ''));
|
|
if ($nm === '') {
|
|
continue;
|
|
}
|
|
$wd = $s['withdrawal_date'] ?? $s['date'] ?? null;
|
|
if ($wd) {
|
|
$withdrawals[] = [
|
|
'name' => $nm,
|
|
'withdrawalDate' => $wd,
|
|
];
|
|
}
|
|
}
|
|
return $withdrawals;
|
|
}
|
|
|
|
private function studentsWithReasons(array $studentdata): array
|
|
{
|
|
$rows = [];
|
|
foreach ($studentdata as $s) {
|
|
$nm = !empty($s['name'])
|
|
? trim((string) $s['name'])
|
|
: trim((string) ($s['firstname'] ?? '') . ' ' . (string) ($s['lastname'] ?? ''));
|
|
if ($nm === '') {
|
|
continue;
|
|
}
|
|
$rows[] = [
|
|
'name' => $nm,
|
|
'reason' => $s['reason'] ?? null,
|
|
];
|
|
}
|
|
return $rows;
|
|
}
|
|
|
|
private function notifyParent(int $userId, string $title, string $message, string $topic): void
|
|
{
|
|
if ($userId <= 0) {
|
|
return;
|
|
}
|
|
$this->notifier->notifyUser($userId, $title, $message, ['in_app'], $topic, 'parent');
|
|
}
|
|
|
|
private function sendEmail(string $to, string $subject, string $html, string $fromKey): array
|
|
{
|
|
if ($to === '') {
|
|
Log::warning('Enrollment event: missing recipient email', ['subject' => $subject]);
|
|
return ['ok' => false, 'message' => 'Missing recipient email.'];
|
|
}
|
|
|
|
$ok = $this->emailService->send($to, $subject, $html, $fromKey);
|
|
if (!$ok) {
|
|
Log::error('Enrollment event email failed', ['to' => $to, 'subject' => $subject]);
|
|
}
|
|
return ['ok' => $ok];
|
|
}
|
|
|
|
private function renderEmail(string $viewName, array $data, string $fallbackTitle): string
|
|
{
|
|
Log::debug('Skipping Blade email template', ['view' => $viewName]);
|
|
|
|
return '<p>' . e($fallbackTitle) . '</p>';
|
|
}
|
|
}
|