DashboardService.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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 DashboardService
  14. {
  15. public function __construct() {}
  16. public function dadosDashboardCliente(): array
  17. {
  18. $user = Auth::user();
  19. $cliente = Client::where('user_id', $user->id)->first();
  20. $headerBar = [
  21. 'rating' => $cliente->average_rating,
  22. 'total_ratings' => Review::where('reviews.origin', 'provider')
  23. ->leftJoin('schedules', 'schedules.id', '=', 'reviews.schedule_id')
  24. ->where('schedules.client_id', $cliente->id)
  25. ->count(),
  26. 'total_services' => $cliente->total_services,
  27. ];
  28. $address = Address::where('source', 'client')
  29. ->where('source_id', $cliente->id)
  30. ->with(['city', 'state'])
  31. ->first();
  32. $summaryInfos = [
  33. 'name' => $user->name,
  34. 'address' => $address,
  35. 'pending_services' => Schedule::where('client_id', $cliente->id)
  36. ->where('status', 'pending')
  37. ->count(),
  38. ];
  39. $nextSchedules = Schedule::with('address:district,address,number,source_id,source,id,address_type')
  40. ->where('schedules.client_id', $cliente->id)
  41. ->whereIn('schedules.status', ['accepted', 'paid'])
  42. ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
  43. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  44. ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
  45. ->where('schedules.date', '>=', now()->toDateString())
  46. ->select(
  47. 'schedules.id',
  48. 'schedules.provider_id',
  49. 'provider_user.name as provider_name',
  50. 'schedules.date',
  51. 'schedules.start_time',
  52. 'schedules.end_time',
  53. 'schedules.total_amount',
  54. 'schedules.period_type',
  55. 'schedules.schedule_type',
  56. 'schedules.address_id',
  57. 'custom_schedules.address_type as custom_address_type',
  58. )
  59. ->orderBy('schedules.date', 'asc')
  60. ->get();
  61. $lastDoneSchedules = Schedule::where('schedules.client_id', $cliente->id)
  62. ->where('schedules.status', 'finished')
  63. ->leftJoin('providers', 'providers.id', '=', 'schedules.provider_id')
  64. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  65. ->select(
  66. 'schedules.id',
  67. 'schedules.provider_id',
  68. 'provider_user.name as provider_name',
  69. )
  70. ->orderBy('schedules.date', 'desc')
  71. ->limit(5)
  72. ->get();
  73. $favoriteProviders = ClientFavoriteProvider::where('client_favorite_providers.client_id', $cliente->id)
  74. ->leftJoin('providers', 'providers.id', '=', 'client_favorite_providers.provider_id')
  75. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  76. ->select(
  77. 'providers.id as provider_id',
  78. 'provider_user.name as provider_name',
  79. 'providers.average_rating',
  80. 'providers.daily_price_8h',
  81. 'providers.daily_price_6h',
  82. 'providers.daily_price_4h',
  83. 'providers.daily_price_2h',
  84. )
  85. ->get();
  86. $blockedProviderIds = ScheduleBusinessRules::getBlockedProviderIdsForClient($cliente->id);
  87. $providersWithWorkingDays = ScheduleBusinessRules::getProviderIdsWithWorkingDays();
  88. $providersClose = Provider::leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  89. ->leftJoin('addresses as provider_address', function ($join) {
  90. $join->on('provider_address.source_id', '=', 'providers.id')
  91. ->where('provider_address.source', 'provider');
  92. })
  93. ->leftJoin('addresses as client_address', function ($join) use ($cliente) {
  94. $join->where('client_address.source_id', $cliente->id)
  95. ->where('client_address.source', 'client');
  96. })
  97. ->whereColumn('provider_address.city_id', '=', 'client_address.city_id')
  98. ->whereNotIn('providers.id', $blockedProviderIds)
  99. ->whereIn('providers.id', $providersWithWorkingDays)
  100. ->where(function ($query) {
  101. $query->whereNotNull('providers.daily_price_8h')
  102. ->orWhereNotNull('providers.daily_price_6h')
  103. ->orWhereNotNull('providers.daily_price_4h')
  104. ->orWhereNotNull('providers.daily_price_2h');
  105. })
  106. ->select(
  107. 'providers.id as provider_id',
  108. 'provider_user.name as provider_name',
  109. 'provider_address.district',
  110. 'providers.average_rating',
  111. DB::raw("(
  112. SELECT COUNT(*)
  113. FROM reviews
  114. LEFT JOIN schedules ON schedules.id = reviews.schedule_id
  115. WHERE reviews.origin = 'provider'
  116. AND schedules.provider_id = providers.id
  117. ) as total_reviews"),
  118. 'providers.total_services',
  119. 'providers.daily_price_8h',
  120. 'providers.daily_price_6h',
  121. 'providers.daily_price_4h',
  122. 'providers.daily_price_2h',
  123. )
  124. ->get();
  125. return [
  126. 'headerBar' => $headerBar,
  127. 'summaryInfos' => $summaryInfos,
  128. 'nextSchedules' => $nextSchedules,
  129. 'lastDoneSchedules' => $lastDoneSchedules,
  130. 'favoriteProviders' => $favoriteProviders,
  131. 'providersClose' => $providersClose,
  132. ];
  133. }
  134. public function dadosDashboardPrestador(): array
  135. {
  136. $user = Auth::user();
  137. $provider = Provider::where('user_id', $user->id)->first();
  138. $headerBar = [
  139. 'rating' => $provider->average_rating,
  140. 'total_ratings' => Review::where('reviews.origin', 'client')->leftJoin('schedules', 'schedules.id', '=', 'reviews.schedule_id')->where('schedules.provider_id', $provider->id)->count(),
  141. 'total_services' => $provider->total_services,
  142. ];
  143. $address = Address::where('source', 'provider')->where('source_id', $provider->id)->with(['city', 'state'])->first();
  144. $summaryInfos = [
  145. 'name' => $user->name,
  146. 'address' => $address,
  147. 'pending_services' => Schedule::where('provider_id', $provider->id)->where('status', 'pending')->count(),
  148. ];
  149. $priceSuggestedAvg = Provider::where('user_id', '!=', $user->id)
  150. ->whereNotNull('daily_price_8h')
  151. ->pluck('daily_price_8h')
  152. ->avg();
  153. $priceActual = $provider->daily_price_8h;
  154. $priceSuggested = [
  155. 'average_price' => $priceSuggestedAvg,
  156. 'your_price' => $priceActual,
  157. ];
  158. $solicitations = Schedule::with('address:district,source_id,source,id')
  159. ->where('schedules.provider_id', $provider->id)
  160. ->where('schedules.status', 'pending')
  161. ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
  162. ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
  163. ->select(
  164. 'schedules.id',
  165. 'client_user.name as client_name',
  166. 'clients.average_rating',
  167. 'schedules.date',
  168. DB::raw("TO_CHAR(schedules.date, 'DD/MM/YYYY') as formatted_date"),
  169. 'schedules.start_time',
  170. 'schedules.end_time',
  171. 'schedules.total_amount',
  172. 'schedules.period_type',
  173. 'schedules.schedule_type',
  174. 'schedules.address_id',
  175. DB::raw("CASE
  176. WHEN (now() - schedules.created_at) < INTERVAL '1 day' THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (now() - schedules.created_at)) / 3600), ' hours ago')
  177. ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (now() - schedules.created_at)) / 86400), ' days ago')
  178. END as time_since_request"),
  179. )
  180. ->orderBy('schedules.date', 'asc')
  181. ->get();
  182. $nextSchedules = Schedule::with('address:district,address,number,source_id,source,id')
  183. ->where('schedules.provider_id', $provider->id)
  184. ->whereIn('schedules.status', ['accepted', 'paid'])
  185. ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
  186. ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
  187. ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
  188. ->select(
  189. 'schedules.id',
  190. 'client_user.name as client_name',
  191. 'schedules.date',
  192. 'schedules.start_time',
  193. 'schedules.end_time',
  194. 'schedules.total_amount',
  195. 'schedules.period_type',
  196. 'schedules.address_id',
  197. 'schedules.schedule_type',
  198. 'custom_schedules.offers_meal',
  199. )
  200. ->orderBy('schedules.date', 'asc')
  201. ->get();
  202. $opportunities = Schedule::with('address:district,source_id,source,id')
  203. ->where('schedules.schedule_type', 'custom')
  204. ->where('schedules.status', 'pending')
  205. ->leftJoin('clients', 'clients.id', '=', 'schedules.client_id')
  206. ->leftJoin('users as client_user', 'client_user.id', '=', 'clients.user_id')
  207. ->leftJoin('custom_schedules', 'custom_schedules.schedule_id', '=', 'schedules.id')
  208. ->select(
  209. 'schedules.id',
  210. 'client_user.name as client_name',
  211. 'clients.average_rating',
  212. 'schedules.date',
  213. 'schedules.start_time',
  214. 'schedules.end_time',
  215. 'schedules.period_type',
  216. 'schedules.schedule_type',
  217. 'schedules.address_id',
  218. 'custom_schedules.address_type'
  219. )
  220. ->orderBy('schedules.date', 'asc')
  221. ->get();
  222. $opportunities = $opportunities->map(function ($item) use ($provider) {
  223. $price = 0;
  224. switch ($item->period_type) {
  225. case 2:
  226. $price = $provider->daily_price_2h;
  227. break;
  228. case 4:
  229. $price = $provider->daily_price_4h;
  230. break;
  231. case 6:
  232. $price = $provider->daily_price_6h;
  233. break;
  234. case 8:
  235. $price = $provider->daily_price_8h;
  236. break;
  237. }
  238. $item->total_amount = $price;
  239. return $item;
  240. });
  241. return [
  242. 'headerBar' => $headerBar,
  243. 'summaryInfos' => $summaryInfos,
  244. 'priceSuggested' => $priceSuggested,
  245. 'solicitations' => $solicitations,
  246. 'nextSchedules' => $nextSchedules,
  247. 'opportunities' => $opportunities,
  248. ];
  249. }
  250. }