where('restaurant_id', $filters['restaurant_id']); } if (! empty($filters['date'])) { $query->whereDate('reservation_date', $filters['date']); } if (! empty($filters['status'])) { $query->where('status', $filters['status']); } if (! empty($filters['search'])) { $search = $filters['search']; $query->where(function ($q) use ($search) { $q->where('note', 'like', "%$search%"); }); } $sortBy = $filters['sort_by'] ?? 'reservation_date'; $sortOrder = $filters['sort_order'] ?? 'desc'; $query->orderBy($sortBy, $sortOrder); $perPage = $filters['perPage'] ?? 10; return $query->paginate($perPage); } public function store(array $data) { $this->checkAvailability($data); return Reservation::create($data); } public function checkAvailability(array $data) { $date = $data['reservation_date']; $start = $data['start_time']; $end = $data['end_time']; $tableId = $data['table_id']; // check unavailable tables $unavailable = ReservationUnavailable::where('table_id', $tableId) ->where('date', $date) ->where(function ($q) use ($start, $end) { $q->whereBetween('start_time', [$start, $end]) ->orWhereBetween('end_time', [$start, $end]); }) ->exists(); if ($unavailable) { throw new Exception('This table is unavailable for the selected time.'); } // check existing reservations $conflict = Reservation::where('table_id', $tableId) ->where('reservation_date', $date) ->where(function ($q) use ($start, $end) { $q->whereBetween('start_time', [$start, $end]) ->orWhereBetween('end_time', [$start, $end]); }) ->whereNotIn('status', ['cancelled']) ->exists(); if ($conflict) { throw new Exception('This table is already booked for the selected time.'); } return true; } }