ManualPushService.php 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\PushNotificationCategoryEnum;
  4. use App\Enums\PushNotificationTargetEnum;
  5. use App\Jobs\SendManualPushJob;
  6. use App\Models\PushNotificationLog;
  7. use App\Models\User;
  8. use Illuminate\Database\Eloquent\Collection;
  9. use Illuminate\Pagination\LengthAwarePaginator;
  10. class ManualPushService
  11. {
  12. private const CHUNK_SIZE = 50;
  13. public function recipients(PushNotificationTargetEnum $target, ?string $search = null): Collection
  14. {
  15. return User::query()
  16. ->whereHas($this->relationFor($target))
  17. ->when($search, function ($query) use ($search) {
  18. $query->where(function ($sub) use ($search) {
  19. $sub->where('name', 'like', "%{$search}%")
  20. ->orWhere('email', 'like', "%{$search}%");
  21. });
  22. })
  23. ->withCount(['deviceTokens as active_device_tokens_count' => fn ($q) => $q
  24. ->where('app_type', $target->value)
  25. ->where('active', true),
  26. ])
  27. ->orderBy('name')
  28. ->get(['id', 'name', 'email', 'push_notifications_enabled']);
  29. }
  30. /**
  31. * Enfileira o envio manual e devolve quantos destinatários foram aceitos.
  32. *
  33. * @param int[] $userIds
  34. */
  35. public function send(PushNotificationTargetEnum $target, array $userIds, string $title, string $body): int
  36. {
  37. $validIds = User::whereIn('id', $userIds)
  38. ->whereHas($this->relationFor($target))
  39. ->pluck('id');
  40. foreach ($validIds->chunk(self::CHUNK_SIZE) as $chunk) {
  41. SendManualPushJob::dispatch($chunk->values()->all(), $title, $body, $target);
  42. }
  43. return $validIds->count();
  44. }
  45. public function history(int $page = 1, int $perPage = 10, ?string $search = null): LengthAwarePaginator
  46. {
  47. return PushNotificationLog::query()
  48. ->where('category', PushNotificationCategoryEnum::MANUAL->value)
  49. ->with('user:id,name,email')
  50. ->when($search, fn ($query) => $query->where(function ($sub) use ($search) {
  51. $sub->where('title', 'like', "%{$search}%")
  52. ->orWhereHas('user', fn ($user) => $user
  53. ->where('name', 'like', "%{$search}%")
  54. ->orWhere('email', 'like', "%{$search}%")
  55. );
  56. }))
  57. ->orderBy('sent_at', 'desc')
  58. ->paginate($perPage, ['*'], 'page', $page);
  59. }
  60. //
  61. private function relationFor(PushNotificationTargetEnum $target): string
  62. {
  63. return $target === PushNotificationTargetEnum::PRESTADOR ? 'provider' : 'client';
  64. }
  65. }