orderBy('date', 'desc') ->get(); } public function getAllByUser(int $userId): Collection { return Appointment::with(['partnerAgreement', 'partnerAgreementService']) ->where('user_id', $userId) ->orderBy('date', 'desc') ->get(); } public function findById(int $id): ?Appointment { return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])->find($id); } public function create(array $data): Appointment { $data['order_number'] = $this->generateOrderNumber(); $data['requested_at'] = now(); return Appointment::create($data); } public function update(int $id, array $data): ?Appointment { $model = Appointment::find($id); if (!$model) { return null; } $model->update($data); return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']); } public function delete(int $id): bool { $model = Appointment::find($id); if (!$model) { return false; } return $model->delete(); } public function getAdminCounters(): array { return [ 'pendentes' => Appointment::where('status', AppointmentStatusEnum::PENDENTE)->count(), 'aprovados' => Appointment::where('status', AppointmentStatusEnum::CONFIRMADO)->count(), 'recusados' => Appointment::where('status', AppointmentStatusEnum::RECUSADO)->count(), ]; } public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator { $query = Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService']) ->orderBy('requested_at', 'desc'); if (!empty($filters['status'])) { $query->where('status', $filters['status']); } if (!empty($filters['search'])) { $term = '%' . mb_strtolower($filters['search']) . '%'; $query->where(function ($q) use ($term) { $q->whereHas('user', function ($uq) use ($term) { $uq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]); })->orWhereHas('partnerAgreement', function ($pq) use ($term) { $pq->whereRaw('UNACCENT(LOWER(COALESCE(trade_name, company_name))) LIKE UNACCENT(?)', [$term]); })->orWhereHas('partnerAgreementService', function ($sq) use ($term) { $sq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]); })->orWhereRaw('UNACCENT(LOWER(order_number)) LIKE UNACCENT(?)', [$term]); }); } return $query->paginate($perPage); } public function approve(int $id): ?Appointment { $model = Appointment::find($id); if (!$model) return null; $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]); return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']); } public function reject(int $id): ?Appointment { $model = Appointment::find($id); if (!$model) return null; $model->update(['status' => AppointmentStatusEnum::RECUSADO]); return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']); } private function generateOrderNumber(): string { do { $number = 'AGD-' . strtoupper(Str::random(8)); } while (Appointment::where('order_number', $number)->exists()); return $number; } }