ReviewService.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. namespace App\Services;
  3. use App\Models\Client;
  4. use App\Models\ClientFavoriteProvider;
  5. use App\Models\ClientProviderBlock;
  6. use App\Models\Provider;
  7. use App\Models\ProviderClientBlock;
  8. use App\Models\Review;
  9. use App\Models\ReviewMedia;
  10. use App\Models\Schedule;
  11. use Exception;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Support\Facades\Log;
  14. use Illuminate\Support\Facades\Storage;
  15. class ReviewService
  16. {
  17. public function __construct(private readonly MediaService $mediaService) {}
  18. public function getAll()
  19. {
  20. return Review::with(['schedule.client.user', 'schedule.provider.user', 'reviewsImprovements.improvementType'])
  21. ->orderBy('created_at', 'desc')
  22. ->get();
  23. }
  24. public function create(array $data): Review
  25. {
  26. try {
  27. DB::beginTransaction();
  28. $review = new Review();
  29. $review->fill($data);
  30. $review->save();
  31. $review->refresh();
  32. if (data_get($data, 'origin') !== null && data_get($data, 'origin_id') !== null) {
  33. switch (data_get($data, 'origin')) {
  34. case 'client':
  35. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  36. $provider = Provider::find($schedule->provider_id);
  37. $provider->updateAverageRating((float) data_get($data, 'stars'));
  38. break;
  39. case 'provider':
  40. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  41. $client = Client::find($schedule->client_id);
  42. $client->updateAverageRating((float) data_get($data, 'stars'));
  43. break;
  44. }
  45. }
  46. if (data_get($data, 'improvements_ids') !== null) {
  47. $review->improvements()->sync(data_get($data, 'improvements_ids'));
  48. }
  49. if (! empty(data_get($data, 'block_provider'))) {
  50. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  51. $alreadyBlocked = ClientProviderBlock::where('client_id', $schedule->client_id)
  52. ->where('provider_id', $schedule->provider_id)
  53. ->whereNull('deleted_at')
  54. ->exists();
  55. if (! $alreadyBlocked) {
  56. ClientProviderBlock::create([
  57. 'client_id' => $schedule->client_id,
  58. 'provider_id' => $schedule->provider_id,
  59. ]);
  60. }
  61. }
  62. if (! empty(data_get($data, 'block_client'))) {
  63. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  64. $alreadyBlocked = ProviderClientBlock::where('provider_id', $schedule->provider_id)
  65. ->where('client_id', $schedule->client_id)
  66. ->whereNull('deleted_at')
  67. ->exists();
  68. if (! $alreadyBlocked) {
  69. ProviderClientBlock::create([
  70. 'provider_id' => $schedule->provider_id,
  71. 'client_id' => $schedule->client_id,
  72. ]);
  73. }
  74. }
  75. if (! empty(data_get($data, 'favorite_provider'))) {
  76. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  77. $alreadyFavorited = ClientFavoriteProvider::where('client_id', $schedule->client_id)
  78. ->where('provider_id', $schedule->provider_id)
  79. ->whereNull('deleted_at')
  80. ->exists();
  81. if (! $alreadyFavorited) {
  82. ClientFavoriteProvider::create([
  83. 'client_id' => $schedule->client_id,
  84. 'provider_id' => $schedule->provider_id,
  85. ]);
  86. }
  87. }
  88. if (! empty(data_get($data, 'photos'))) {
  89. $schedule = Schedule::find(data_get($data, 'schedule_id'));
  90. $origin = data_get($data, 'origin');
  91. foreach (data_get($data, 'photos') as $photo) {
  92. $media = $this->mediaService->createFromFile(
  93. file: $photo,
  94. folder: "review/{$schedule->id}/{$origin}",
  95. source: 'review',
  96. sourceId: $review->id,
  97. );
  98. ReviewMedia::create([
  99. 'review_id' => $review->id,
  100. 'media_id' => $media->id,
  101. 'origin' => $origin,
  102. ]);
  103. }
  104. }
  105. DB::commit();
  106. return $review;
  107. } catch (Exception $e) {
  108. DB::rollBack();
  109. Log::error('Erro ao criar avaliação: '.$e->getMessage());
  110. throw $e;
  111. }
  112. }
  113. public function update(int $id, array $data): Review
  114. {
  115. $review = Review::findOrFail($id);
  116. $review->update($data);
  117. return $review->fresh();
  118. }
  119. public function delete(int $id): bool
  120. {
  121. $review = Review::findOrFail($id);
  122. return $review->delete();
  123. }
  124. //
  125. public function getByClientReceived(int $clientId)
  126. {
  127. return Review::with($this->detailEagerLoads())
  128. ->whereIn('origin', ['provider', 'providers'])
  129. ->whereHas('schedule', fn ($q) => $q->where('client_id', $clientId))
  130. ->orderBy('created_at', 'desc')
  131. ->get();
  132. }
  133. public function getByClientSent(int $clientId)
  134. {
  135. return Review::with($this->detailEagerLoads())
  136. ->whereIn('origin', ['client', 'clients'])
  137. ->where('origin_id', $clientId)
  138. ->orderBy('created_at', 'desc')
  139. ->get();
  140. }
  141. public function getByProviderReceived(int $providerId)
  142. {
  143. $reviews = Review::with($this->detailEagerLoads())
  144. ->whereIn('origin', ['client', 'clients'])
  145. ->whereHas('schedule', fn ($q) => $q->where('provider_id', $providerId))
  146. ->orderBy('created_at', 'desc')
  147. ->get();
  148. foreach ($reviews as $review) {
  149. if ($review->schedule?->client?->profileMedia?->path) {
  150. $review->schedule->client->profile_photo = Storage::temporaryUrl($review->schedule->client->profileMedia->path, now()->addMinutes(60));
  151. } else {
  152. $review->schedule->client->profile_photo = null;
  153. }
  154. }
  155. return $reviews;
  156. }
  157. public function getByProviderSent(int $providerId)
  158. {
  159. return Review::with($this->detailEagerLoads())
  160. ->whereIn('origin', ['provider', 'providers'])
  161. ->where('origin_id', $providerId)
  162. ->orderBy('created_at', 'desc')
  163. ->get();
  164. }
  165. //
  166. public function getByOrigin(string $origin, int $originId)
  167. {
  168. return Review::with(['schedule.client.user', 'schedule.provider.user'])
  169. ->where('origin', $origin)
  170. ->where('origin_id', $originId)
  171. ->orderBy('created_at', 'desc')
  172. ->get();
  173. }
  174. public function getByScheduleId(int $scheduleId)
  175. {
  176. return Review::with(['schedule.client.user', 'schedule.provider.user'])
  177. ->where('schedule_id', $scheduleId)
  178. ->orderBy('created_at', 'desc')
  179. ->get();
  180. }
  181. //
  182. private function detailEagerLoads(): array
  183. {
  184. return [
  185. 'schedule.client.user',
  186. 'schedule.client.profileMedia',
  187. 'schedule.provider.user',
  188. 'schedule.address.city',
  189. 'schedule.address.state',
  190. 'schedule.customSchedule.serviceType',
  191. 'schedule.customSchedule.specialities',
  192. 'improvements',
  193. ];
  194. }
  195. }