NotificationService.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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', 'notification.media'])
  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 createAutoForUser(array $data, int $userId): Notification
  82. {
  83. $data['created_by'] = Auth::id();
  84. $data['type'] = 'automatica';
  85. $notification = Notification::create($data);
  86. NotificationSend::create([
  87. 'notification_id' => $notification->id,
  88. 'user_id' => $userId,
  89. 'read' => false,
  90. ]);
  91. return $notification;
  92. }
  93. public function delete(int $id): bool
  94. {
  95. $model = Notification::find($id);
  96. if (!$model) {
  97. return false;
  98. }
  99. return $model->delete();
  100. }
  101. private function dispatchSends(Notification $notification): void
  102. {
  103. $query = User::query();
  104. match ($notification->recipient) {
  105. NotificationRecipientEnum::ASSOCIADO => $query->where('type', UserTypeEnum::ASSOCIADO->value),
  106. NotificationRecipientEnum::PARCEIRO => $query->where('type', UserTypeEnum::PARCEIRO->value),
  107. default => null,
  108. };
  109. if ($notification->recipient_position_id) {
  110. $query->where('position_id', $notification->recipient_position_id);
  111. }
  112. if ($notification->recipient_sector_id) {
  113. $query->where('sector_id', $notification->recipient_sector_id);
  114. }
  115. $users = $query->pluck('id');
  116. $sends = $users->map(fn($userId) => [
  117. 'notification_id' => $notification->id,
  118. 'user_id' => $userId,
  119. 'read' => false,
  120. 'created_at' => now(),
  121. 'updated_at' => now(),
  122. ])->toArray();
  123. NotificationSend::insert($sends);
  124. }
  125. }