157 lines
6.5 KiB
PHP
157 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\ClientProjectActivities;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
|
|
class PendingProjectActivitiesNotify extends Command
|
|
{
|
|
protected $signature = 'project-activities:pending-notify {--test-email= : Send a sample reminder email to this address only}';
|
|
|
|
protected $description = 'Notify users about pending project activities based on estimated completion date';
|
|
|
|
public function handle(): int
|
|
{
|
|
try {
|
|
if ($this->option('test-email')) {
|
|
return $this->sendTestEmail($this->option('test-email'));
|
|
}
|
|
|
|
$today = Carbon::today();
|
|
$tomorrow = Carbon::tomorrow();
|
|
|
|
$activities = ClientProjectActivities::query()
|
|
->with(['client:id,name,customer_id', 'user:id,name,email'])
|
|
->whereNull('completed_at')
|
|
->whereNotNull('estimated_completed_at')
|
|
->whereDate('estimated_completed_at', '<=', $tomorrow)
|
|
->orderBy('estimated_completed_at')
|
|
->get();
|
|
|
|
$activities
|
|
->groupBy('user_id')
|
|
->each(function ($userActivities, $userId) use ($today, $tomorrow) {
|
|
$user = $userActivities->first()->user;
|
|
|
|
if (! $user || empty($user->email)) {
|
|
$this->warn("Skipping project activity reminder for user_id={$userId}; no valid email found.");
|
|
|
|
return;
|
|
}
|
|
|
|
$overdue = $userActivities->filter(function (ClientProjectActivities $activity) use ($today) {
|
|
return $activity->estimated_completed_at->lt($today);
|
|
});
|
|
|
|
$dueToday = $userActivities->filter(function (ClientProjectActivities $activity) use ($today) {
|
|
return $activity->estimated_completed_at->isSameDay($today);
|
|
});
|
|
|
|
$dueTomorrow = $userActivities->filter(function (ClientProjectActivities $activity) use ($tomorrow) {
|
|
return $activity->estimated_completed_at->isSameDay($tomorrow);
|
|
});
|
|
|
|
if ($overdue->isEmpty() && $dueToday->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
$mailData = [
|
|
'user_name' => $user->name,
|
|
'role_label' => 'Activity Owner',
|
|
'overdue' => $overdue->map(fn (ClientProjectActivities $activity) => $this->formatActivity($activity, $today))->values()->all(),
|
|
'due_today' => $dueToday->map(fn (ClientProjectActivities $activity) => $this->formatActivity($activity, $today))->values()->all(),
|
|
'due_tomorrow' => $dueTomorrow->map(fn (ClientProjectActivities $activity) => $this->formatActivity($activity, $today))->values()->all(),
|
|
];
|
|
|
|
Mail::send('mail.project_activity_reminder', ['data' => $mailData], function ($message) use ($user) {
|
|
$message->to($user->email, $user->name)
|
|
->subject('Pending Project Activity Reminder');
|
|
});
|
|
|
|
$this->info("Sent pending project activity reminder to {$user->email} ({$user->name}).");
|
|
});
|
|
|
|
return self::SUCCESS;
|
|
} catch (\Throwable $e) {
|
|
Log::error('Error sending pending project activity reminders: '.$e->getMessage(), [
|
|
'trace' => $e->getTraceAsString(),
|
|
]);
|
|
|
|
$this->error('Failed to send pending project activity reminders.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
}
|
|
|
|
private function formatActivity(ClientProjectActivities $activity, Carbon $today): array
|
|
{
|
|
$estimatedDate = $activity->estimated_completed_at->copy()->startOfDay();
|
|
|
|
return [
|
|
'activity_no' => $activity->activity_no,
|
|
'customer_id' => $activity->client?->customer_id ?? '-',
|
|
'customer' => $activity->client?->name ?? '-',
|
|
'activity_type' => $activity->activity_type ?? '-',
|
|
'task_description' => $activity->task_description ?? '-',
|
|
'estimated_completed_at' => $estimatedDate->format('Y-m-d'),
|
|
'number_of_days' => (int) $today->diffInDays($estimatedDate, false),
|
|
];
|
|
}
|
|
|
|
private function sendTestEmail(string $email): int
|
|
{
|
|
$today = Carbon::today();
|
|
|
|
$mailData = [
|
|
'user_name' => 'Brian',
|
|
'role_label' => 'Activity Owner',
|
|
'overdue' => [
|
|
[
|
|
'activity_no' => 'ACT0001',
|
|
'customer_id' => '1234567890',
|
|
'customer' => 'Example Client A',
|
|
'activity_type' => 'scheduled',
|
|
'task_description' => 'Review SEM performance report and update client notes.',
|
|
'estimated_completed_at' => $today->copy()->subDays(2)->format('Y-m-d'),
|
|
'number_of_days' => -2,
|
|
],
|
|
],
|
|
'due_today' => [
|
|
[
|
|
'activity_no' => 'ACT0002',
|
|
'customer_id' => '1234567891',
|
|
'customer' => 'Example Client B',
|
|
'activity_type' => 'scheduled',
|
|
'task_description' => 'Prepare optimisation checklist for campaign review.',
|
|
'estimated_completed_at' => $today->format('Y-m-d'),
|
|
'number_of_days' => 0,
|
|
],
|
|
],
|
|
'due_tomorrow' => [
|
|
[
|
|
'activity_no' => 'ACT0003',
|
|
'customer_id' => '1234567892',
|
|
'customer' => 'Example Client C',
|
|
'activity_type' => 'scheduled',
|
|
'task_description' => 'Follow up on budget pacing and next-month planning.',
|
|
'estimated_completed_at' => $today->copy()->addDay()->format('Y-m-d'),
|
|
'number_of_days' => 1,
|
|
],
|
|
],
|
|
];
|
|
|
|
Mail::send('mail.project_activity_reminder', ['data' => $mailData], function ($message) use ($email) {
|
|
$message->to($email)
|
|
->subject('Test: Pending Project Activity Reminder');
|
|
});
|
|
|
|
$this->info("Sent test pending project activity reminder to {$email}.");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|