| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <?php
- namespace App\Services;
- use App\Enums\PushNotificationCategoryEnum;
- use App\Enums\PushNotificationTargetEnum;
- use App\Jobs\SendManualPushJob;
- use App\Models\PushNotificationLog;
- use App\Models\User;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Pagination\LengthAwarePaginator;
- class ManualPushService
- {
- private const CHUNK_SIZE = 50;
- public function recipients(PushNotificationTargetEnum $target, ?string $search = null): Collection
- {
- return User::query()
- ->whereHas($this->relationFor($target))
- ->when($search, function ($query) use ($search) {
- $query->where(function ($sub) use ($search) {
- $sub->where('name', 'like', "%{$search}%")
- ->orWhere('email', 'like', "%{$search}%");
- });
- })
- ->withCount(['deviceTokens as active_device_tokens_count' => fn ($q) => $q
- ->where('app_type', $target->value)
- ->where('active', true),
- ])
- ->orderBy('name')
- ->get(['id', 'name', 'email', 'push_notifications_enabled']);
- }
- /**
- * Enfileira o envio manual e devolve quantos destinatários foram aceitos.
- *
- * @param int[] $userIds
- */
- public function send(PushNotificationTargetEnum $target, array $userIds, string $title, string $body): int
- {
- $validIds = User::whereIn('id', $userIds)
- ->whereHas($this->relationFor($target))
- ->pluck('id');
- foreach ($validIds->chunk(self::CHUNK_SIZE) as $chunk) {
- SendManualPushJob::dispatch($chunk->values()->all(), $title, $body, $target);
- }
- return $validIds->count();
- }
- public function history(int $page = 1, int $perPage = 10, ?string $search = null): LengthAwarePaginator
- {
- return PushNotificationLog::query()
- ->where('category', PushNotificationCategoryEnum::MANUAL->value)
- ->with('user:id,name,email')
- ->when($search, fn ($query) => $query->where(function ($sub) use ($search) {
- $sub->where('title', 'like', "%{$search}%")
- ->orWhereHas('user', fn ($user) => $user
- ->where('name', 'like', "%{$search}%")
- ->orWhere('email', 'like', "%{$search}%")
- );
- }))
- ->orderBy('sent_at', 'desc')
- ->paginate($perPage, ['*'], 'page', $page);
- }
- //
- private function relationFor(PushNotificationTargetEnum $target): string
- {
- return $target === PushNotificationTargetEnum::PRESTADOR ? 'provider' : 'client';
- }
- }
|