inspiren-sem-tool/app/Console/Commands/CampaignEndingNotifiy.php
brian-inspiren 221d3f8173
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
feat: sem codebase
2026-05-21 11:28:03 +08:00

111 lines
4.5 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Client;
use App\Models\GoogleCampaign;
use App\Models\GoogleClient;
use App\Models\ClientUserAssignation;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Services\GoogleAdsService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Carbon\Carbon;
class CampaignEndingNotifiy extends Command
{
protected $signature = 'campaign:ending-notify';
protected $description = 'Notify about campaigns that are ending soon';
public function handle()
{
try {
DB::beginTransaction();
$this->info("Fetching campaign details from Google Ads...");
$adsService = new GoogleAdsService();
$today = Carbon::today();
$threshold = Carbon::today()->addDays(30);
// Get all assignations with users
$assignations = ClientUserAssignation::with('user')->where('role',ClientUserAssignation::ROLE_ASSIGNED_PERSON)->get();
// Group assignations by user_id and role
$groupedAssignations = $assignations->groupBy(['user_id', 'role']);
foreach ($groupedAssignations as $userId => $roles) {
foreach ($roles as $role => $assigns) {
$clientIds = $assigns->pluck('client_id');
$clients = Client::whereIn('id', $clientIds)->where('status', 'ENABLED')->get();
$endingCampaigns = [];
foreach ($clients as $client) {
$campaigns = $adsService->listCampaigns($client->customer_id);
foreach ($campaigns as $campaign) {
if (empty($campaign['end_date'])) {
continue; // skip if no end date
}
$endDate = Carbon::parse($campaign['end_date']);
// Condition: ending within 30 days AND not already ended
if ($endDate->between($today, $threshold)) {
$endingCampaigns[] = [
'client' => $client,
'campaign' => $campaign,
'end_date' => $endDate,
];
}
}
}
// Notify the user if there are ending campaigns
if (!empty($endingCampaigns)) {
$user = $assigns->first()->user;
$roleLabel = $role == ClientUserAssignation::ROLE_ASSIGNED_PERSON ? 'Assigned Person' : 'Sales Person';
if ($user && !empty($user->email)) {
$mailData = [
'user_name' => $user->name,
'role_label' => $roleLabel,
'to_expiry' => array_map(function ($item) use ($today) {
return [
'id'=>$item['client']->customer_id,
'title' => $item['client']->name,
'name' => $item['campaign']['name'],
'iteration_end_date' => $item['end_date']->format('Y-m-d'),
'number_of_days' => $today->diffInDays($item['end_date']),
];
}, $endingCampaigns),
];
Mail::send('mail.campaign_expiry', ['data' => $mailData], function ($message) use ($user) {
$message->to($user->email, $user->name)
->subject('Campaign Expiry Alert');
});
$this->info("Sent campaign expiry email to {$user->email} ({$user->name}, {$roleLabel}).");
} else {
$this->warn("Skipping email for assignation group without valid email: user_id={$userId}, role={$role}");
}
}
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
Log::error('Error getting campaign details: ' . $e->getMessage(), [
'trace' => $e->getTraceAsString(),
]);
return 1;
}
}
}