ReviewService.php 7.0 KB

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