info("正在掃描公共事業費狀態..."); // 1. 更新逾期狀態 (pending -> overdue) \App\Modules\Finance\Models\UtilityFee::where('payment_status', \App\Modules\Finance\Models\UtilityFee::STATUS_PENDING) ->whereNotNull('due_date') ->where('due_date', '<', now()->startOfDay()) ->update(['payment_status' => \App\Modules\Finance\Models\UtilityFee::STATUS_OVERDUE]); // 2. 獲取可能需要處理的單據 (pending 或 overdue) $feesToCheck = \App\Modules\Finance\Models\UtilityFee::whereIn('payment_status', [ \App\Modules\Finance\Models\UtilityFee::STATUS_PENDING, \App\Modules\Finance\Models\UtilityFee::STATUS_OVERDUE ]) ->whereNotNull('due_date') ->orderBy('due_date', 'asc') ->get(); if ($feesToCheck->isEmpty()) { $this->info("目前沒有未繳納的公共事業費。"); return 0; } // 3. 根據業務規則過濾出今天「真正」需要發信的單據 $today = now()->startOfDay(); $unpaidFees = $feesToCheck->filter(function ($fee) use ($today) { $dueDate = \Illuminate\Support\Carbon::parse($fee->due_date)->startOfDay(); $diffInDays = $today->diffInDays($dueDate, false); // 如果已經逾期 (overdue),每天都要發信 if ($fee->payment_status === \App\Modules\Finance\Models\UtilityFee::STATUS_OVERDUE) { return true; } // 如果是待繳納 (pending),僅在特定天數發信 // 規則:到期前 7 天、3 天、當天 (0 天) return in_array($diffInDays, [7, 3, 0]); }); if ($unpaidFees->isEmpty()) { $this->info("今日無符合發信條件的公共事業費提醒。"); return 0; } // 4. 讀取系統設定 $senderEmail = \App\Modules\Core\Models\SystemSetting::getVal('notification.utility_fee_sender_email'); $senderPassword = \App\Modules\Core\Models\SystemSetting::getVal('notification.utility_fee_sender_password'); $recipientEmailsStr = \App\Modules\Core\Models\SystemSetting::getVal('notification.utility_fee_recipient_emails'); if (empty($senderEmail) || empty($senderPassword) || empty($recipientEmailsStr)) { $this->warn("系統設定中缺乏完整的 Email 通知參數,跳過寄送通知。請至「系統設定」->「通知設定」完善資料。"); return 0; } // 4. 動態覆寫應用程式名稱與 SMTP Config $tenantName = tenant('name') ?? config('app.name'); config([ 'app.name' => $tenantName, 'mail.mailers.smtp.username' => $senderEmail, 'mail.mailers.smtp.password' => $senderPassword, 'mail.from.address' => $senderEmail, 'mail.from.name' => $tenantName . ' (系統通知)' ]); // 清理原先可能的 Mailer 實例,確保使用新的 Config \Illuminate\Support\Facades\Mail::purge(); // 5. 解析收件者並寄送 Email $recipients = array_map('trim', explode(',', $recipientEmailsStr)); $validRecipients = array_filter($recipients, fn($e) => filter_var($e, FILTER_VALIDATE_EMAIL)); if (empty($validRecipients)) { $this->warn("無效的收件者 Email 格式,跳過寄送通知。"); return 0; } try { \Illuminate\Support\Facades\Mail::to($validRecipients)->send(new \App\Mail\PaymentReminderMail($unpaidFees)); $this->info("通知郵件已成功寄送至: " . implode(', ', $validRecipients)); } catch (\Exception $e) { $this->error("Email 寄送失敗: " . $e->getMessage()); } return 0; } }