diff --git a/app/Jobs/SendCertificateEmailJob.php b/app/Jobs/SendCertificateEmailJob.php index 32b54e1..b77e99a 100644 --- a/app/Jobs/SendCertificateEmailJob.php +++ b/app/Jobs/SendCertificateEmailJob.php @@ -2,26 +2,69 @@ namespace App\Jobs; +use App\Mail\CertificateReadyMail; use App\Models\Certificate; +use App\Models\EmailLog; use App\Models\Program; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Mail; class SendCertificateEmailJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public int $tries = 3; + public int $tries = 3; public int $backoff = 60; public function __construct(public readonly Certificate $certificate) {} public function handle(): void { - // Implemented in Fasa 8 — email blast + $cert = $this->certificate->refresh(); + $cert->load(['participant', 'program']); + + $email = $cert->participant->email; + + if (! $email) { + return; + } + + try { + Mail::to($email)->send(new CertificateReadyMail($cert)); + + $cert->update([ + 'status' => 'emailed', + 'emailed_at' => now(), + ]); + + EmailLog::create([ + 'program_id' => $cert->program_id, + 'participant_id' => $cert->participant_id, + 'certificate_id' => $cert->id, + 'recipient_email'=> $email, + 'subject' => 'Sijil Digital Program — ' . $cert->program->title, + 'email_type' => 'certificate_ready', + 'status' => 'sent', + 'sent_at' => now(), + ]); + } catch (\Throwable $e) { + EmailLog::create([ + 'program_id' => $cert->program_id, + 'participant_id' => $cert->participant_id, + 'certificate_id' => $cert->id, + 'recipient_email'=> $email, + 'subject' => 'Sijil Digital Program — ' . $cert->program->title, + 'email_type' => 'certificate_ready', + 'status' => 'failed', + 'error_message' => $e->getMessage(), + ]); + + throw $e; + } } public static function dispatchBatch(Program $program): void @@ -29,6 +72,11 @@ class SendCertificateEmailJob implements ShouldQueue $program->certificates() ->whereIn('status', ['generated']) ->whereNull('emailed_at') - ->each(fn($cert) => static::dispatch($cert)); + ->with('participant') + ->each(function (Certificate $cert) { + if ($cert->participant->email) { + static::dispatch($cert); + } + }); } } diff --git a/app/Mail/CertificateReadyMail.php b/app/Mail/CertificateReadyMail.php new file mode 100644 index 0000000..71b10ca --- /dev/null +++ b/app/Mail/CertificateReadyMail.php @@ -0,0 +1,31 @@ +certificate->program->title, + ); + } + + public function content(): Content + { + return new Content( + view: 'emails.certificate-ready', + ); + } +} diff --git a/resources/views/emails/certificate-ready.blade.php b/resources/views/emails/certificate-ready.blade.php new file mode 100644 index 0000000..d0efcc0 --- /dev/null +++ b/resources/views/emails/certificate-ready.blade.php @@ -0,0 +1,87 @@ + + + + + + Sijil Digital — {{ $certificate->program->title }} + + + +
+
+

🏆 Sijil Digital (eCert)

+

{{ $certificate->program->organizer ?? config('app.name') }}

+
+ +
+

Salam sejahtera, {{ $certificate->participant->name }},

+ +

+ Terima kasih kerana menghadiri program di bawah. Sijil digital anda telah sedia untuk dimuat turun. +

+ +
+ + + + + + @if($certificate->program->start_date) + + + + + @endif + @if($certificate->certificate_no) + + + + + @endif +
Program{{ $certificate->program->title }}
Tarikh Program{{ $certificate->program->start_date->format('d M Y') }}
No. Sijil{{ $certificate->certificate_no }}
+
+ +

Klik butang di bawah untuk memuat turun sijil anda:

+ +
+ + Muat Turun Sijil Saya + +
+ +

+ Pautan di atas adalah unik untuk anda. Sila simpan emel ini sebagai rujukan. + Jika anda menghadapi sebarang masalah, sila hubungi penganjur program. +

+
+ + +
+ +