AppointmentService.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\AppointmentStatusEnum;
  4. use App\Models\Appointment;
  5. use Illuminate\Database\Eloquent\Collection;
  6. use Illuminate\Pagination\LengthAwarePaginator;
  7. use Illuminate\Support\Str;
  8. class AppointmentService
  9. {
  10. public function getAll(): Collection
  11. {
  12. return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
  13. ->orderBy('date', 'desc')
  14. ->get();
  15. }
  16. public function getAllByUser(int $userId): Collection
  17. {
  18. return Appointment::with(['partnerAgreement', 'partnerAgreementService'])
  19. ->where('user_id', $userId)
  20. ->orderBy('date', 'desc')
  21. ->get();
  22. }
  23. public function getAllByPartnerUser(int $userId): Collection
  24. {
  25. return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
  26. ->whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))
  27. ->orderBy('date', 'desc')
  28. ->get();
  29. }
  30. public function findById(int $id): ?Appointment
  31. {
  32. return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])->find($id);
  33. }
  34. public function create(array $data): Appointment
  35. {
  36. $data['order_number'] = $this->generateOrderNumber();
  37. $data['requested_at'] = now();
  38. return Appointment::create($data);
  39. }
  40. public function update(int $id, array $data): ?Appointment
  41. {
  42. $model = Appointment::find($id);
  43. if (!$model) {
  44. return null;
  45. }
  46. $model->update($data);
  47. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  48. }
  49. public function delete(int $id): bool
  50. {
  51. $model = Appointment::find($id);
  52. if (!$model) {
  53. return false;
  54. }
  55. return $model->delete();
  56. }
  57. public function getAdminCounters(): array
  58. {
  59. return [
  60. 'pendentes' => Appointment::where('status', AppointmentStatusEnum::PENDENTE)->count(),
  61. 'aprovados' => Appointment::where('status', AppointmentStatusEnum::CONFIRMADO)->count(),
  62. 'recusados' => Appointment::where('status', AppointmentStatusEnum::RECUSADO)->count(),
  63. ];
  64. }
  65. public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
  66. {
  67. $query = Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
  68. ->orderBy('requested_at', 'desc');
  69. if (!empty($filters['status'])) {
  70. $query->where('status', $filters['status']);
  71. }
  72. if (!empty($filters['search'])) {
  73. $term = '%' . mb_strtolower($filters['search']) . '%';
  74. $query->where(function ($q) use ($term) {
  75. $q->whereHas('user', function ($uq) use ($term) {
  76. $uq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
  77. })->orWhereHas('partnerAgreement', function ($pq) use ($term) {
  78. $pq->whereRaw('UNACCENT(LOWER(COALESCE(trade_name, company_name))) LIKE UNACCENT(?)', [$term]);
  79. })->orWhereHas('partnerAgreementService', function ($sq) use ($term) {
  80. $sq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
  81. })->orWhereRaw('UNACCENT(LOWER(order_number)) LIKE UNACCENT(?)', [$term]);
  82. });
  83. }
  84. return $query->paginate($perPage);
  85. }
  86. public function approve(int $id): ?Appointment
  87. {
  88. $model = Appointment::find($id);
  89. if (!$model) return null;
  90. $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
  91. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  92. }
  93. public function reject(int $id): ?Appointment
  94. {
  95. $model = Appointment::find($id);
  96. if (!$model) return null;
  97. $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
  98. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  99. }
  100. public function approveByPartner(int $id, int $userId): ?Appointment
  101. {
  102. $model = Appointment::whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))->find($id);
  103. if (!$model) return null;
  104. $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
  105. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  106. }
  107. public function rejectByPartner(int $id, int $userId): ?Appointment
  108. {
  109. $model = Appointment::whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))->find($id);
  110. if (!$model) return null;
  111. $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
  112. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  113. }
  114. private function generateOrderNumber(): string
  115. {
  116. do {
  117. $number = 'AGD-' . strtoupper(Str::random(8));
  118. } while (Appointment::where('order_number', $number)->exists());
  119. return $number;
  120. }
  121. }