ProviderService.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\UserTypeEnum;
  4. use App\Models\Address;
  5. use App\Models\City;
  6. use App\Models\Provider;
  7. use App\Models\ProviderServicesType;
  8. use App\Models\ProviderWorkingDay;
  9. use App\Models\State;
  10. use App\Models\User;
  11. use Illuminate\Database\Eloquent\Collection;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Support\Facades\Log;
  14. class ProviderService
  15. {
  16. public function __construct(
  17. private readonly AuthService $authService,
  18. ) {}
  19. public function getAll(): Collection
  20. {
  21. $providers = Provider::query()
  22. ->with(['user', 'profileMedia'])
  23. ->orderBy('created_at', 'desc')
  24. ->get();
  25. return $providers;
  26. }
  27. public function findById(int $id): ?Provider
  28. {
  29. return Provider::with(['user', 'profileMedia'])->find($id);
  30. }
  31. public function create(array $data): Provider
  32. {
  33. return Provider::create($data);
  34. }
  35. public function update(int $id, array $data): ?Provider
  36. {
  37. $model = $this->findById($id);
  38. if (!$model) {
  39. return null;
  40. }
  41. $model->update($data);
  42. return $model->fresh(['user', 'profileMedia']);
  43. }
  44. public function delete(int $id): bool
  45. {
  46. $model = $this->findById($id);
  47. if (!$model) {
  48. return false;
  49. }
  50. return $model->delete();
  51. }
  52. public function register(array $data): ?array
  53. {
  54. try {
  55. DB::beginTransaction();
  56. $email = $data['email'] ?? null;
  57. $phone = $data['phone'] ?? null;
  58. $code = $data['code'] ?? null;
  59. $user = User::query()
  60. ->where('type', UserTypeEnum::PROVIDER->value)
  61. ->where('code', $code)
  62. ->where(function ($query) use ($email, $phone) {
  63. if (!empty($email)) {
  64. $query->orWhere('email', $email);
  65. }
  66. if (!empty($phone)) {
  67. $query->orWhere('phone', $phone);
  68. }
  69. })
  70. ->latest('id')
  71. ->first();
  72. if (!$user) {
  73. throw new \Exception(__('messages.user_not_found_or_code_not_validated'));
  74. }
  75. $user->name = $data['name'];
  76. if (empty($user->email) && !empty($email)) {
  77. $user->email = $email;
  78. }
  79. if (empty($user->phone) && !empty($phone)) {
  80. $user->phone = $phone;
  81. }
  82. $user->save();
  83. $provider = new Provider();
  84. $provider->user_id = $user->id;
  85. $provider->rg = $data['rg'] ?? null;
  86. $provider->document = $this->sanitizeDigits($data['document'] ?? null);
  87. $provider->birth_date = $data['birth_date'] ?? null;
  88. $provider->daily_price_8h = $data['daily_price_8h'] ?? null;
  89. $provider->daily_price_6h = $data['daily_price_6h'] ?? null;
  90. $provider->daily_price_4h = $data['daily_price_4h'] ?? null;
  91. $provider->daily_price_2h = $data['daily_price_2h'] ?? null;
  92. $provider->is_approved = false;
  93. $provider->selfie_media_base64 = $data['selfie_base64'] ?? null;
  94. $provider->document_front_media_base64 = $data['document_front_base64'] ?? null;
  95. $provider->document_back_media_base64 = $data['document_back_base64'] ?? null;
  96. $provider->save();
  97. $provider->refresh();
  98. $this->createProviderAddress($provider->id, $data);
  99. $this->createProviderServicesTypes($provider->id, $data);
  100. $this->createProviderWorkingDays($provider->id, $data);
  101. if (empty($user->email) || empty($user->code)) {
  102. throw new \Exception(__('messages.user_not_found_or_code_not_validated'));
  103. }
  104. $result = $this->authService->loginWithEmail(
  105. email: $user->email,
  106. code: $user->code,
  107. );
  108. DB::commit();
  109. return $result;
  110. } catch (\Exception $e) {
  111. DB::rollBack();
  112. Log::error('Error registering provider: ' . $e->getMessage(), [
  113. 'data' => $data,
  114. ]);
  115. throw $e;
  116. }
  117. }
  118. private function createProviderAddress(int $providerId, array $data): void
  119. {
  120. $state = null;
  121. $city = null;
  122. if (!empty($data['state'])) {
  123. $state = State::query()
  124. ->whereRaw('LOWER(code) = ?', [mb_strtolower($data['state'])])
  125. ->first();
  126. }
  127. if (!empty($data['city'])) {
  128. $cityQuery = City::query()
  129. ->whereRaw('LOWER(name) = ?', [mb_strtolower($data['city'])]);
  130. if ($state) {
  131. $cityQuery->where('state_id', $state->id);
  132. }
  133. $city = $cityQuery->first();
  134. }
  135. $address = new Address();
  136. $address->source = 'provider';
  137. $address->source_id = $providerId;
  138. $address->zip_code = $this->sanitizeDigits($data['zip_code'] ?? null);
  139. $address->address = $data['address'] ?? null;
  140. $address->has_complement = (bool) ($data['has_complement'] ?? false);
  141. $address->complement = $data['complement'] ?? null;
  142. $address->nickname = $data['nickname'] ?? null;
  143. $address->instructions = $data['instructions'] ?? null;
  144. $address->address_type = $data['address_type'] ?? 'home';
  145. $address->state_id = $state?->id;
  146. $address->city_id = $city?->id;
  147. $address->save();
  148. }
  149. private function createProviderServicesTypes(int $providerId, array $data): void
  150. {
  151. $serviceTypeIds = $data['services_types_ids'] ?? $data['service_types_ids'] ?? [];
  152. $uniqueIds = array_values(array_unique(array_map('intval', $serviceTypeIds)));
  153. foreach ($uniqueIds as $serviceTypeId) {
  154. ProviderServicesType::create([
  155. 'provider_id' => $providerId,
  156. 'service_type_id' => $serviceTypeId,
  157. ]);
  158. }
  159. }
  160. private function createProviderWorkingDays(int $providerId, array $data): void
  161. {
  162. $workingDays = $data['working_days'] ?? [];
  163. $seen = [];
  164. foreach ($workingDays as $workingDay) {
  165. $day = (int) ($workingDay['day'] ?? -1);
  166. $period = $workingDay['period'] ?? null;
  167. if ($day < 0 || $day > 6 || !in_array($period, ['morning', 'afternoon'], true)) {
  168. continue;
  169. }
  170. $uniqueKey = $day . '-' . $period;
  171. if (isset($seen[$uniqueKey])) {
  172. continue;
  173. }
  174. $seen[$uniqueKey] = true;
  175. ProviderWorkingDay::create([
  176. 'provider_id' => $providerId,
  177. 'day' => $day,
  178. 'period' => $period,
  179. ]);
  180. }
  181. }
  182. private function sanitizeDigits(?string $value): ?string
  183. {
  184. if ($value === null) {
  185. return null;
  186. }
  187. $digits = preg_replace('/\D+/', '', $value);
  188. return $digits === '' ? null : $digits;
  189. }
  190. }