1+ <?php
2+
3+ namespace App\Console\Commands;
4+
5+ use App\Models\Task;
6+ use Illuminate\Console\Command;
7+ use Illuminate\Support\Facades\Log;
8+ use Illuminate\Notifications\Messages\MailMessage;
9+ use Illuminate\Support\Facades\Notification;
10+
11+ class SendDueSoonTaskNotifications extends Command
12+ {
13+ /**
14+ * The name and signature of the console command.
15+ *
16+ * @var string
17+ */
18+ protected $signature = 'tasks:send-due-soon-notifications {--days=3 : Number of days ahead to check}';
19+
20+ /**
21+ * The console command description.
22+ *
23+ * @var string
24+ */
25+ protected $description = 'Send due soon task notifications to users';
26+
27+ /**
28+ * Execute the console command.
29+ */
30+ public function handle()
31+ {
32+ $days = (int) $this->option('days');
33+
34+ // Get tasks due within the specified days that haven't been completed
35+ $dueSoonTasks = Task::with(['assignedTo', 'assignedBy'])
36+ ->where('status', '!=', 'completed')
37+ ->where('deadline', '>=', now())
38+ ->where('deadline', '<=', now()->addDays($days))
39+ ->get();
40+
41+ $this->info("Found {$dueSoonTasks->count()} tasks due within {$days} days.");
42+
43+ $notifiedCount = 0;
44+ $errorCount = 0;
45+
46+ foreach ($dueSoonTasks as $task) {
47+ try {
48+ // Send custom due soon notification
49+ $task->assignedTo->notify(new class($task) extends \Illuminate\Notifications\Notification {
50+ use \Illuminate\Bus\Queueable;
51+ use \Illuminate\Contracts\Queue\ShouldQueue;
52+
53+ public function __construct(public $task) {}
54+
55+ public function via($notifiable): array
56+ {
57+ return ['mail'];
58+ }
59+
60+ public function toMail($notifiable): MailMessage
61+ {
62+ $daysUntilDue = now()->diffInDays($this->task->deadline, false);
63+ $dueText = $daysUntilDue === 0 ? 'today' : "in {$daysUntilDue} day" . ($daysUntilDue > 1 ? 's' : '');
64+
65+ return (new MailMessage)
66+ ->subject('📅 Task Due Soon: ' . $this->task->title)
67+ ->greeting('Hello ' . $notifiable->name . '!')
68+ ->line('📅 **Reminder: You have a task due soon!**')
69+ ->line('**Task Title:** ' . $this->task->title)
70+ ->line('**Description:** ' . ($this->task->description ?: 'No description provided'))
71+ ->line('**Due:** ' . $this->task->deadline->format('F j, Y \a\t g:i A') . " ({$dueText})")
72+ ->line('**Current Status:** ' . ucfirst(str_replace('_', ' ', $this->task->status)))
73+ ->action('Update Task Status', url('/dashboard'))
74+ ->line('Please review and update the task status as needed.');
75+ }
76+ });
77+
78+ $notifiedCount++;
79+ $this->line("✓ Notified {$task->assignedTo->name} about task due soon: {$task->title}");
80+ } catch (\Exception $e) {
81+ $errorCount++;
82+ Log::error("Failed to send due soon notification for task {$task->id}: " . $e->getMessage());
83+ $this->error("✗ Failed to notify {$task->assignedTo->name} about task: {$task->title}");
84+ }
85+ }
86+
87+ $this->info("Notification summary:");
88+ $this->info("- Successfully sent: {$notifiedCount}");
89+ $this->info("- Errors: {$errorCount}");
90+
91+ return 0;
92+ }
93+ }
0 commit comments