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; } } }