62 lines
2.4 KiB
PHP
62 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Models\SystemNotificationCampaign;
|
|
use App\Models\User;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Queue\Queueable;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class ProcessSystemNotificationCampaign implements ShouldQueue
|
|
{
|
|
use Queueable;
|
|
|
|
public function __construct(public int $campaignId) {}
|
|
|
|
public function handle(): void
|
|
{
|
|
$campaign = SystemNotificationCampaign::find($this->campaignId);
|
|
if (! $campaign || $campaign->status === 'completed') {
|
|
return;
|
|
}
|
|
|
|
$campaign->update(['status' => 'processing']);
|
|
$query = $this->audienceQuery($campaign);
|
|
$campaign->update(['estimated_recipients' => (clone $query)->count()]);
|
|
|
|
$query->select('users.id')->chunkById(500, function ($users) use ($campaign) {
|
|
$now = now();
|
|
DB::table('user_notifications')->insertOrIgnore($users->map(fn ($user) => [
|
|
'uuid' => Str::uuid(),
|
|
'tenant_id' => $campaign->tenant_id,
|
|
'user_id' => $user->id,
|
|
'system_notification_campaign_id' => $campaign->id,
|
|
'title' => $campaign->title,
|
|
'body' => $campaign->body,
|
|
'action_url' => $campaign->action_url,
|
|
'icon' => $campaign->icon,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
])->all());
|
|
$campaign->increment('processed_recipients', $users->count());
|
|
});
|
|
$campaign->update(['status' => 'completed', 'completed_at' => now()]);
|
|
}
|
|
|
|
private function audienceQuery(SystemNotificationCampaign $campaign)
|
|
{
|
|
$audience = $campaign->audience;
|
|
|
|
return User::query()
|
|
->whereNull('deleted_at')
|
|
->when($audience['statuses'] ?? null, fn ($q, $values) => $q->whereIn('status', $values))
|
|
->when(! $campaign->tenant_id && ($audience['access_levels'] ?? null), fn ($q) => $q->whereIn('access_level', $audience['access_levels']))
|
|
->when($audience['user_ids'] ?? null, fn ($q, $values) => $q->whereIn('id', $values))
|
|
->when($campaign->tenant_id, fn ($q, $tenantId) => $q->whereHas('userTenants', fn ($x) => $x
|
|
->where('tenant_id', $tenantId)
|
|
->when($audience['access_levels'] ?? null, fn ($roleQuery, $roles) => $roleQuery->whereIn('role', $roles))));
|
|
}
|
|
}
|