urls = $urls ?? app(ApplicationUrlService::class); } 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 '
'.e($fallbackTitle).'
'; } }