AppointmentService.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 findById(int $id): ?Appointment
  24. {
  25. return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])->find($id);
  26. }
  27. public function create(array $data): Appointment
  28. {
  29. $data['order_number'] = $this->generateOrderNumber();
  30. $data['requested_at'] = now();
  31. return Appointment::create($data);
  32. }
  33. public function update(int $id, array $data): ?Appointment
  34. {
  35. $model = Appointment::find($id);
  36. if (!$model) {
  37. return null;
  38. }
  39. $model->update($data);
  40. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  41. }
  42. public function delete(int $id): bool
  43. {
  44. $model = Appointment::find($id);
  45. if (!$model) {
  46. return false;
  47. }
  48. return $model->delete();
  49. }
  50. public function getAdminCounters(): array
  51. {
  52. return [
  53. 'pendentes' => Appointment::where('status', AppointmentStatusEnum::PENDENTE)->count(),
  54. 'aprovados' => Appointment::where('status', AppointmentStatusEnum::CONFIRMADO)->count(),
  55. 'recusados' => Appointment::where('status', AppointmentStatusEnum::RECUSADO)->count(),
  56. ];
  57. }
  58. public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
  59. {
  60. $query = Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
  61. ->orderBy('requested_at', 'desc');
  62. if (!empty($filters['status'])) {
  63. $query->where('status', $filters['status']);
  64. }
  65. if (!empty($filters['search'])) {
  66. $term = '%' . mb_strtolower($filters['search']) . '%';
  67. $query->where(function ($q) use ($term) {
  68. $q->whereHas('user', function ($uq) use ($term) {
  69. $uq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
  70. })->orWhereHas('partnerAgreement', function ($pq) use ($term) {
  71. $pq->whereRaw('UNACCENT(LOWER(COALESCE(trade_name, company_name))) LIKE UNACCENT(?)', [$term]);
  72. })->orWhereHas('partnerAgreementService', function ($sq) use ($term) {
  73. $sq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
  74. })->orWhereRaw('UNACCENT(LOWER(order_number)) LIKE UNACCENT(?)', [$term]);
  75. });
  76. }
  77. return $query->paginate($perPage);
  78. }
  79. public function approve(int $id): ?Appointment
  80. {
  81. $model = Appointment::find($id);
  82. if (!$model) return null;
  83. $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
  84. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  85. }
  86. public function reject(int $id): ?Appointment
  87. {
  88. $model = Appointment::find($id);
  89. if (!$model) return null;
  90. $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
  91. return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
  92. }
  93. private function generateOrderNumber(): string
  94. {
  95. do {
  96. $number = 'AGD-' . strtoupper(Str::random(8));
  97. } while (Appointment::where('order_number', $number)->exists());
  98. return $number;
  99. }
  100. }