ClientFavoriteProviderService.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\ApprovalStatusEnum;
  4. use App\Exceptions\FavoriteProviderException;
  5. use App\Http\Resources\ClientFavoriteProviderResource;
  6. use App\Models\ClientFavoriteProvider;
  7. use App\Models\ClientProviderBlock;
  8. use App\Models\Provider;
  9. use App\Models\ProviderClientBlock;
  10. use Illuminate\Database\Eloquent\Collection;
  11. use Illuminate\Support\Facades\DB;
  12. class ClientFavoriteProviderService
  13. {
  14. public function getByClientId(int $clientId): Collection
  15. {
  16. return ClientFavoriteProvider::where('client_favorite_providers.client_id', $clientId)
  17. ->with('provider.profileMedia')
  18. ->leftJoin('providers', 'providers.id', '=', 'client_favorite_providers.provider_id')
  19. ->whereExists(Provider::hasActivePrimaryBankAccount())
  20. ->leftJoin('users as provider_user', 'provider_user.id', '=', 'providers.user_id')
  21. ->leftJoin('addresses as provider_address', function ($join) {
  22. $join->on('provider_address.source_id', '=', 'providers.id')
  23. ->where('provider_address.source', 'provider')
  24. ->whereNull('provider_address.deleted_at');
  25. })
  26. ->leftJoin('cities', 'cities.id', '=', 'provider_address.city_id')
  27. ->select(
  28. 'client_favorite_providers.id',
  29. 'client_favorite_providers.client_id',
  30. 'client_favorite_providers.provider_id',
  31. 'client_favorite_providers.notes',
  32. 'client_favorite_providers.created_at',
  33. 'client_favorite_providers.updated_at',
  34. 'provider_user.name as provider_name',
  35. 'providers.share_code',
  36. 'providers.gender',
  37. 'providers.average_rating',
  38. 'providers.daily_price_8h',
  39. 'providers.daily_price_6h',
  40. 'providers.daily_price_4h',
  41. 'providers.daily_price_2h',
  42. 'providers.total_services',
  43. 'cities.name as city_name',
  44. )
  45. ->orderBy('client_favorite_providers.created_at', 'desc')
  46. ->get();
  47. }
  48. public function getById(int $id): ClientFavoriteProviderResource
  49. {
  50. $favorite = ClientFavoriteProvider::with(['provider.user', 'provider.profileMedia'])->findOrFail($id);
  51. return new ClientFavoriteProviderResource($favorite);
  52. }
  53. public function create(array $data): ClientFavoriteProviderResource
  54. {
  55. $favorite = ClientFavoriteProvider::create($data);
  56. $favorite->load(['provider.user', 'provider.profileMedia']);
  57. return new ClientFavoriteProviderResource($favorite);
  58. }
  59. public function update(int $id, array $data): ClientFavoriteProviderResource
  60. {
  61. $favorite = ClientFavoriteProvider::findOrFail($id);
  62. $favorite->update($data);
  63. $favorite->load(['provider.user', 'provider.profileMedia']);
  64. return new ClientFavoriteProviderResource($favorite);
  65. }
  66. public function delete(int $id): bool
  67. {
  68. $favorite = ClientFavoriteProvider::findOrFail($id);
  69. return $favorite->delete();
  70. }
  71. //
  72. public function createByCode(int $clientId, string $code): ClientFavoriteProviderResource
  73. {
  74. $code = Provider::normalizeShareCode($code);
  75. $provider = Provider::query()
  76. ->where('share_code', $code)
  77. ->where('approval_status', ApprovalStatusEnum::ACCEPTED->value)
  78. ->visibleToCustomers()
  79. ->with(['user', 'profileMedia'])
  80. ->first();
  81. if (! $provider) {
  82. throw new FavoriteProviderException('favorite_code_not_found', 404);
  83. }
  84. $isBlocked = ProviderClientBlock::where('provider_id', $provider->id)
  85. ->where('client_id', $clientId)
  86. ->exists()
  87. || ClientProviderBlock::where('client_id', $clientId)
  88. ->where('provider_id', $provider->id)
  89. ->exists();
  90. if ($isBlocked) {
  91. throw new FavoriteProviderException('favorite_code_blocked');
  92. }
  93. $favorite = DB::transaction(function () use ($clientId, $provider) {
  94. $alreadyFavorite = ClientFavoriteProvider::where('client_id', $clientId)
  95. ->where('provider_id', $provider->id)
  96. ->exists();
  97. if ($alreadyFavorite) {
  98. throw new FavoriteProviderException('favorite_code_already_favorite');
  99. }
  100. $removed = ClientFavoriteProvider::onlyTrashed()
  101. ->where('client_id', $clientId)
  102. ->where('provider_id', $provider->id)
  103. ->latest('id')
  104. ->first();
  105. if ($removed) {
  106. $removed->restore();
  107. return $removed;
  108. }
  109. return ClientFavoriteProvider::create([
  110. 'client_id' => $clientId,
  111. 'provider_id' => $provider->id,
  112. ]);
  113. });
  114. $favorite->setRelation('provider', $provider);
  115. return new ClientFavoriteProviderResource($favorite);
  116. }
  117. //
  118. public function getFavoritedProviderIds(int $clientId): array
  119. {
  120. return ClientFavoriteProvider::where('client_id', $clientId)
  121. ->pluck('provider_id')
  122. ->toArray();
  123. }
  124. }