SearchService.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. namespace App\Services;
  3. use App\Models\Address;
  4. use App\Models\Client;
  5. use App\Models\ClientFavoriteProvider;
  6. use App\Models\Provider;
  7. use App\Models\Review;
  8. use App\Models\Schedule;
  9. use App\Rules\ScheduleBusinessRules;
  10. use Illuminate\Support\Facades\Auth;
  11. use Illuminate\Support\Facades\DB;
  12. use Illuminate\Support\Facades\Log;
  13. class SearchService
  14. {
  15. public function __construct() {}
  16. public function buscaPrestadores(?string $name = null, ?string $date = null): array
  17. {
  18. $user = Auth::user();
  19. $cliente = Client::where('user_id', $user->id)->first();
  20. $blockedProviderIds = ScheduleBusinessRules::getBlockedProviderIdsForClient($cliente->id);
  21. $providersWithWorkingDays = ScheduleBusinessRules::getProviderIdsWithWorkingDays();
  22. $clientPrimaryAddress = Address::where('source', 'client')
  23. ->where('source_id', $cliente->id)
  24. ->orderBy('is_primary', 'desc')
  25. ->first();
  26. return Provider::leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  27. ->leftJoin(DB::raw("
  28. (
  29. SELECT DISTINCT ON (source_id)
  30. *
  31. FROM addresses
  32. WHERE source = 'provider'
  33. ORDER BY source_id, is_primary DESC
  34. ) as provider_address
  35. "), 'provider_address.source_id', '=', 'providers.id')
  36. ->whereNotNull('provider_address.id')
  37. ->where('provider_address.city_id', $clientPrimaryAddress?->city_id)
  38. ->whereNotIn('providers.id', $blockedProviderIds)
  39. ->whereIn('providers.id', $providersWithWorkingDays)
  40. ->whereNotNull('providers.daily_price_8h')
  41. ->whereNotNull('providers.daily_price_6h')
  42. ->whereNotNull('providers.daily_price_4h')
  43. ->whereNotNull('providers.daily_price_2h')
  44. ->when($name, fn($q) => $q->where('provider_user.name', 'ILIKE', "%{$name}%"))
  45. ->select(
  46. 'providers.id as provider_id',
  47. 'provider_user.name as provider_name',
  48. 'provider_address.district',
  49. 'providers.average_rating',
  50. 'providers.total_services',
  51. 'providers.daily_price_8h',
  52. 'providers.daily_price_6h',
  53. 'providers.daily_price_4h',
  54. 'providers.daily_price_2h',
  55. 'providers.created_at',
  56. DB::raw("(
  57. SELECT COUNT(*)
  58. FROM reviews
  59. LEFT JOIN schedules ON schedules.id = reviews.schedule_id
  60. WHERE reviews.origin = 'provider'
  61. AND schedules.provider_id = providers.id
  62. ) as total_reviews"),
  63. )
  64. ->orderBy('providers.average_rating', 'desc')
  65. ->get()
  66. ->when(
  67. $date,
  68. fn($collection) => $collection->whereIn(
  69. 'provider_id',
  70. ScheduleBusinessRules::getAvailableProviderIdsForDate(
  71. $date,
  72. $collection->pluck('provider_id')
  73. )->toArray()
  74. )->values()
  75. )
  76. ->toArray();
  77. }
  78. }