NotificationService.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\NotificationRecipientEnum;
  4. use App\Enums\UserTypeEnum;
  5. use App\Models\Notification;
  6. use App\Models\NotificationSend;
  7. use App\Models\User;
  8. use Illuminate\Contracts\Pagination\LengthAwarePaginator;
  9. use Illuminate\Database\Eloquent\Collection;
  10. use Illuminate\Http\UploadedFile;
  11. use Illuminate\Support\Facades\Auth;
  12. use Illuminate\Support\Facades\DB;
  13. class NotificationService
  14. {
  15. public function __construct(protected MediaService $mediaService) {}
  16. public function getAll(): Collection
  17. {
  18. return Notification::with('createdBy')->orderBy('created_at', 'desc')->get();
  19. }
  20. public function getAllPaginated(int $perPage = 12): LengthAwarePaginator
  21. {
  22. return Notification::with(['createdBy', 'media'])
  23. ->withCount([
  24. 'sends',
  25. 'sends as seen_count' => fn($q) => $q->where('read', true),
  26. ])
  27. ->orderBy('created_at', 'desc')
  28. ->paginate($perPage);
  29. }
  30. public function findById(int $id): ?Notification
  31. {
  32. return Notification::with(['createdBy', 'sends', 'media'])->find($id);
  33. }
  34. public function create(array $data): Notification
  35. {
  36. return DB::transaction(function () use ($data) {
  37. $image = null;
  38. if (isset($data['image']) && $data['image'] instanceof UploadedFile) {
  39. $image = $data['image'];
  40. }
  41. unset($data['image']);
  42. $data['created_by'] = Auth::id();
  43. $data['type'] = $data['type'] ?? 'manual';
  44. $notification = Notification::create($data);
  45. if ($image) {
  46. $this->mediaService->upload($image, 'notification', $notification->id, 'imagem');
  47. }
  48. $this->dispatchSends($notification);
  49. return $notification->load('media');
  50. });
  51. }
  52. public function getUnreadByUser(int $userId): Collection
  53. {
  54. return NotificationSend::with('notification')
  55. ->where('user_id', $userId)
  56. ->where('read', false)
  57. ->orderBy('created_at', 'desc')
  58. ->get();
  59. }
  60. public function getByUser(int $userId): Collection
  61. {
  62. return NotificationSend::with([
  63. 'notification',
  64. 'notification.media',
  65. ])
  66. ->where('user_id', $userId)
  67. ->orderBy('created_at', 'desc')
  68. ->get();
  69. }
  70. public function markAsRead(int $sendId, int $userId): bool
  71. {
  72. $send = NotificationSend::where('id', $sendId)
  73. ->where('user_id', $userId)
  74. ->first();
  75. if (!$send) {
  76. return false;
  77. }
  78. $send->update(['read' => true, 'read_at' => now()]);
  79. return true;
  80. }
  81. public function delete(int $id): bool
  82. {
  83. $model = Notification::find($id);
  84. if (!$model) {
  85. return false;
  86. }
  87. return $model->delete();
  88. }
  89. private function dispatchSends(Notification $notification): void
  90. {
  91. $query = User::query();
  92. match ($notification->recipient) {
  93. NotificationRecipientEnum::ASSOCIADO => $query->where('type', UserTypeEnum::ASSOCIADO->value),
  94. NotificationRecipientEnum::PARCEIRO => $query->where('type', UserTypeEnum::PARCEIRO->value),
  95. default => null,
  96. };
  97. if ($notification->recipient_position_id) {
  98. $query->where('position_id', $notification->recipient_position_id);
  99. }
  100. if ($notification->recipient_sector_id) {
  101. $query->where('sector_id', $notification->recipient_sector_id);
  102. }
  103. $users = $query->pluck('id');
  104. $sends = $users->map(fn($userId) => [
  105. 'notification_id' => $notification->id,
  106. 'user_id' => $userId,
  107. 'read' => false,
  108. 'created_at' => now(),
  109. 'updated_at' => now(),
  110. ])->toArray();
  111. NotificationSend::insert($sends);
  112. }
  113. }