payload( $service, $invoice, $months, $previousExpiresAt, $payment === 'balance' ? 'Trừ số dư tài khoản' : 'Đã thu ngoài hệ thống', ) + ['admin_name' => $adminName]; AutoEmailGate::markManual(); $this->safely(fn () => $this->sendToCustomer($service, $data, $adminId)); $this->safely(fn () => $this->sendToAdmin($data)); } public function notifyCustomerRenewal( Service $service, Invoice $invoice, int $months, ?CarbonInterface $previousExpiresAt, ): void { if (! AutoEmailGate::allows(self::CUSTOMER_SCENARIO)) { return; } $paymentLabel = $invoice->payment_method === 'balance' ? 'Trừ số dư tài khoản' : (string) ($invoice->payment_method ?: 'N/A'); $data = $this->payload($service, $invoice, $months, $previousExpiresAt, $paymentLabel); $this->safely(fn () => $this->sendToCustomer($service, $data, null)); } private function payload(Service $service, Invoice $invoice, int $months, ?CarbonInterface $previousExpiresAt, string $paymentLabel): array { $service->loadMissing(['customer', 'product']); $customer = $service->customer; $serverName = (string) $service->server_name; $amount = number_format((float) $invoice->total, 0, ',', '.') . ' VNĐ'; return [ 'client_name' => $customer->fullname ?? '', 'customer_name' => $customer->fullname ?? '', 'customer_email' => $customer->email ?? '', 'product_name' => $service->product?->name ?? 'Dịch vụ', 'server_name_suffix' => $serverName !== '' ? ' (' . e($serverName) . ')' : '', 'months_label' => "{$months} tháng", 'old_expires_at' => $previousExpiresAt?->format('d/m/Y') ?? 'N/A', 'expires_at' => $service->expires_at?->format('d/m/Y') ?? 'N/A', 'invoice_number' => $invoice->invoice_number, 'amount_formatted' => $amount, 'payment_method_label' => $paymentLabel, 'price_row' => EmailTemplateShell::row('Số tiền gia hạn', $amount), ]; } private function sendToCustomer(Service $service, array $data, ?int $adminId): void { $customer = $service->customer; if (! filled($customer?->email)) { return; } $mail = new ServiceRenewedMail(self::CUSTOMER_SCENARIO, $data); $template = $this->templates->loadTemplate(self::CUSTOMER_SCENARIO); MailLog::create([ 'template_id' => $template->id, 'subject' => $mail->envelope()->subject, 'from_address' => $template->mailConfig()['from_email'] ?? config('mail.from.address'), 'to' => $customer->email, 'customer_id' => $customer->id, 'sent_by' => $adminId, 'message' => $mail->render(), ]); Mail::to($customer->email)->queue($mail); } private function sendToAdmin(array $data): void { $adminEmail = json_decode((string) Setting::where('key', 'setting')->value('value'), true)['admin_email'] ?? null; if (! $adminEmail) { Log::warning('ServiceRenewalNotifier: admin_email not configured in settings.'); return; } Mail::to($adminEmail)->queue(new ServiceRenewedMail(self::ADMIN_SCENARIO, $data)); } private function safely(callable $send): void { try { $send(); } catch (\Throwable $e) { Log::error('ServiceRenewalNotifier: failed to send email.', ['error' => $e->getMessage()]); } } }