ClientCalendarService.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\GenderEnum;
  4. use App\Models\Client;
  5. use App\Models\Provider;
  6. use App\Models\Schedule;
  7. use Illuminate\Support\Facades\Auth;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Storage;
  10. class ClientCalendarService
  11. {
  12. public function __construct() {}
  13. public function getCalendar(): array
  14. {
  15. $user = Auth::user();
  16. $client = Client::where('user_id', $user->id)->first();
  17. $selectFields = [
  18. 'schedules.id',
  19. 'schedules.provider_id',
  20. 'schedules.date',
  21. 'schedules.start_time',
  22. 'schedules.end_time',
  23. 'schedules.total_amount',
  24. 'schedules.period_type',
  25. 'schedules.schedule_type',
  26. 'schedules.address_id',
  27. 'schedules.status',
  28. 'custom_schedules.offers_meal',
  29. 'provider_user.name as provider_name',
  30. 'providers.gender',
  31. 'providers.average_rating',
  32. 'providers.total_services',
  33. DB::raw("
  34. EXISTS (
  35. SELECT 1
  36. FROM reviews
  37. WHERE reviews.schedule_id = schedules.id
  38. AND reviews.origin = 'client'
  39. AND reviews.origin_id = {$client->id}
  40. AND reviews.deleted_at IS NULL
  41. ) AS client_reviewed
  42. "),
  43. DB::raw("
  44. (
  45. SELECT reviews.stars
  46. FROM reviews
  47. WHERE reviews.schedule_id = schedules.id
  48. AND reviews.origin = 'client'
  49. AND reviews.origin_id = {$client->id}
  50. AND reviews.deleted_at IS NULL
  51. LIMIT 1
  52. ) AS client_stars
  53. "),
  54. ];
  55. $upcomingSchedules = Schedule::with('address:district,address,number,source_id,source,id')
  56. ->where('schedules.client_id', $client->id)
  57. ->whereIn('schedules.status', ['pending', 'accepted', 'paid', 'started'])
  58. ->where(function ($query) {
  59. $query->where('schedules.schedule_type', '!=', 'custom')
  60. ->orWhereIn('schedules.status', ['paid', 'started']);
  61. })
  62. ->whereDate('schedules.date', '>=', now()->toDateString())
  63. ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
  64. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  65. ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
  66. ->select($selectFields)
  67. ->orderBy('schedules.date', 'asc')
  68. ->orderBy('schedules.start_time', 'asc')
  69. ->get();
  70. $completedSchedules = Schedule::with('address:district,address,number,source_id,source,id')
  71. ->where('schedules.client_id', $client->id)
  72. ->whereIn('schedules.status', ['finished', 'cancelled'])
  73. ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
  74. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  75. ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
  76. ->select($selectFields)
  77. ->orderBy('schedules.date', 'desc')
  78. ->orderBy('schedules.start_time', 'desc')
  79. ->get();
  80. $providerPhotos = Provider::query()
  81. ->select('id', 'profile_media_id')
  82. ->with('profileMedia')
  83. ->whereIn(
  84. 'id',
  85. $upcomingSchedules->pluck('provider_id')
  86. ->merge($completedSchedules->pluck('provider_id'))
  87. ->filter()
  88. ->unique(),
  89. )
  90. ->get()
  91. ->mapWithKeys(fn (Provider $provider) => [
  92. $provider->id => $provider->profileMedia?->path,
  93. ]);
  94. $signPhoto = fn ($item) => tap($item, function ($i) use ($providerPhotos) {
  95. $i->gender_label = GenderEnum::labelFor($i->gender);
  96. $path = $providerPhotos->get($i->provider_id);
  97. $i->provider_photo = $path
  98. ? Storage::temporaryUrl($path, now()->addMinutes(60))
  99. : null;
  100. });
  101. $upcomingSchedules->transform($signPhoto);
  102. $completedSchedules->transform($signPhoto);
  103. return [
  104. 'upcomingSchedules' => $upcomingSchedules,
  105. 'completedSchedules' => $completedSchedules,
  106. ];
  107. }
  108. }