PartnerAgreementService.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\PartnerAgreementStatusEnum;
  4. use App\Enums\UserStatusEnum;
  5. use App\Enums\UserTypeEnum;
  6. use App\Models\PartnerAgreement;
  7. use App\Models\User;
  8. use Illuminate\Database\Eloquent\Builder;
  9. use Illuminate\Database\Eloquent\Collection;
  10. use Illuminate\Pagination\LengthAwarePaginator;
  11. use Illuminate\Support\Facades\DB;
  12. use Illuminate\Support\Facades\Hash;
  13. class PartnerAgreementService
  14. {
  15. public function getAll(array $filters = []): Collection
  16. {
  17. $query = PartnerAgreement::with(['category', 'city', 'logo'])
  18. ->orderBy('company_name');
  19. if (!empty($filters['type'])) {
  20. $query->where('type', $filters['type']);
  21. }
  22. return $query->get();
  23. }
  24. public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
  25. {
  26. $query = $this->baseQuery($filters)
  27. ->with(['category', 'city', 'logo']);
  28. if (!empty($filters['expires_in_days'])) {
  29. $query->orderBy('contract_end');
  30. } else {
  31. $query->orderBy('company_name');
  32. }
  33. if (!empty($filters['status'])) {
  34. $query->where('status', $filters['status']);
  35. }
  36. return $query->paginate($perPage);
  37. }
  38. /**
  39. * Status existentes no conjunto filtrado, desconsiderando o próprio filtro de status.
  40. *
  41. * @return array<int, string>
  42. */
  43. public function getStatusOptions(array $filters = []): array
  44. {
  45. return $this->baseQuery($filters)
  46. ->toBase()
  47. ->distinct()
  48. ->pluck('status')
  49. ->filter()
  50. ->values()
  51. ->all();
  52. }
  53. private function baseQuery(array $filters): Builder
  54. {
  55. $query = PartnerAgreement::query();
  56. if (!empty($filters['type'])) {
  57. $query->where('type', $filters['type']);
  58. }
  59. if (!empty($filters['search'])) {
  60. $term = '%' . mb_strtolower($filters['search']) . '%';
  61. $query->where(function ($q) use ($term) {
  62. $q->whereRaw('UNACCENT(LOWER(company_name)) LIKE UNACCENT(?)', [$term])
  63. ->orWhereRaw('UNACCENT(LOWER(COALESCE(responsible, \'\'))) LIKE UNACCENT(?)', [$term])
  64. ->orWhereRaw('UNACCENT(LOWER(COALESCE(cnpj, \'\'))) LIKE UNACCENT(?)', [$term]);
  65. });
  66. }
  67. if (!empty($filters['expires_in_days'])) {
  68. $days = (int) $filters['expires_in_days'];
  69. $query->whereBetween('contract_end', [now()->startOfDay(), now()->addDays($days)->endOfDay()]);
  70. }
  71. if (!empty($filters['created_month']) && $filters['created_month'] === 'current') {
  72. $query->whereMonth('created_at', now()->month)
  73. ->whereYear('created_at', now()->year);
  74. }
  75. return $query;
  76. }
  77. public function getExpiringPaginated(int $days = 30, int $perPage = 10): LengthAwarePaginator
  78. {
  79. return PartnerAgreement::with(['category', 'city', 'logo'])
  80. ->whereNotNull('contract_end')
  81. ->whereBetween('contract_end', [now()->startOfDay(), now()->addDays($days)->endOfDay()])
  82. ->orderBy('contract_end')
  83. ->paginate($perPage);
  84. }
  85. public function findById(int $id): ?PartnerAgreement
  86. {
  87. return PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media', 'user'])->find($id);
  88. }
  89. public function findByUserId(int $userId): ?PartnerAgreement
  90. {
  91. $partner = PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media'])
  92. ->where('user_id', $userId)
  93. ->first();
  94. if (!$partner) {
  95. if (PartnerAgreement::onlyTrashed()->where('user_id', $userId)->exists()) {
  96. return null;
  97. }
  98. $partner = new PartnerAgreement();
  99. $partner->company_name = 'Novo Parceiro';
  100. $partner->user_id = $userId;
  101. $partner->save();
  102. $partner->fresh(['category', 'city', 'state', 'services', 'logo', 'media']);
  103. }
  104. return $partner;
  105. }
  106. public function findDados(int $id): ?PartnerAgreement
  107. {
  108. return PartnerAgreement::with(['category', 'logo'])->find($id);
  109. }
  110. public function findContato(int $id): ?PartnerAgreement
  111. {
  112. return PartnerAgreement::find($id);
  113. }
  114. public function findEndereco(int $id): ?PartnerAgreement
  115. {
  116. return PartnerAgreement::with(['city', 'state'])->find($id);
  117. }
  118. public function findContrato(int $id): ?PartnerAgreement
  119. {
  120. return PartnerAgreement::with(['media'])->find($id);
  121. }
  122. public function create(array $data): PartnerAgreement
  123. {
  124. $user = User::create([
  125. 'name' => $data['user_name'],
  126. 'email' => $data['user_email'],
  127. 'password' => Hash::make($data['user_password']),
  128. 'type' => UserTypeEnum::PARCEIRO,
  129. ]);
  130. $partnerData = collect($data)
  131. ->except(['user_name', 'user_email', 'user_password'])
  132. ->put('user_id', $user->id)
  133. ->all();
  134. $model = PartnerAgreement::create($partnerData);
  135. return $model->fresh(['category', 'logo', 'user']);
  136. }
  137. public function update(int $id, array $data): ?PartnerAgreement
  138. {
  139. $model = PartnerAgreement::find($id);
  140. if (!$model) {
  141. return null;
  142. }
  143. $model->update($data);
  144. return $model->fresh(['category', 'city', 'state', 'logo', 'media']);
  145. }
  146. public function getTrashed(array $filters = []): Collection
  147. {
  148. $query = PartnerAgreement::onlyTrashed()->orderByDesc('deleted_at');
  149. if (!empty($filters['type'])) {
  150. $query->where('type', $filters['type']);
  151. }
  152. return $query->get(['id', 'company_name', 'type', 'deleted_at']);
  153. }
  154. public function restore(int $id): ?PartnerAgreement
  155. {
  156. $model = PartnerAgreement::onlyTrashed()->find($id);
  157. if (!$model) {
  158. return null;
  159. }
  160. return DB::transaction(function () use ($model): PartnerAgreement {
  161. $model->restore();
  162. $model->update(['status' => PartnerAgreementStatusEnum::ACTIVE]);
  163. $model->user?->update(['status' => UserStatusEnum::ACTIVE]);
  164. return $model->fresh();
  165. });
  166. }
  167. public function delete(int $id): bool
  168. {
  169. $model = PartnerAgreement::find($id);
  170. if (!$model) {
  171. return false;
  172. }
  173. return DB::transaction(function () use ($model): bool {
  174. $model->services()->delete();
  175. $model->user?->update(['status' => UserStatusEnum::INACTIVE]);
  176. $model->update(['status' => PartnerAgreementStatusEnum::INACTIVE]);
  177. return (bool) $model->delete();
  178. });
  179. }
  180. }