Files
alrahma_sunday_school_api/app/Services/School/EnrollmentEventService.php
T
2026-06-09 02:32:58 -04:00

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>';
}
}