validate([ 'room_type_id' => 'required|exists:room_types,id', 'check_in' => 'required|date|after_or_equal:today', 'check_out' => 'required|date|after:check_in', 'guest_name' => 'required|string|max:255', 'guest_email' => 'required|email', 'guest_phone' => 'required|string', 'confirmation_type' => 'required|in:auto,manual', ]); $roomType = RoomType::findOrFail($validated['room_type_id']); $dates = []; $currentDate = new \DateTime($validated['check_in']); $endDate = new \DateTime($validated['check_out']); while ($currentDate < $endDate) { $dates[] = $currentDate->format('Y-m-d'); $currentDate->modify('+1 day'); } $unavailableDates = RoomAvailability::where('room_type_id', $roomType->id) ->whereIn('date', $dates) ->where('is_available', false) ->pluck('date') ->toArray(); if (!empty($unavailableDates)) { throw ValidationException::withMessages([ 'check_in' => [ 'The following dates are not available: ' . implode(', ', $unavailableDates) ], ]); } DB::beginTransaction(); try { $booking = Booking::create([ 'room_type_id' => $validated['room_type_id'], 'check_in' => $validated['check_in'], 'check_out' => $validated['check_out'], 'guest_name' => $validated['guest_name'], 'guest_email' => $validated['guest_email'], 'guest_phone' => $validated['guest_phone'], 'status' => $validated['confirmation_type'] === 'auto' ? 'confirmed' : 'pending', 'confirmed_at' => $validated['confirmation_type'] === 'auto' ? now() : null, 'created_by_user_id' => $request->user()->id, // ← ID админа ]); DB::commit(); return response()->json($booking, 201); } catch (\Exception $e) { DB::rollback(); throw $e; } } public function index(Request $request) { $query = \App\Models\Booking::with(['roomType', 'roomType.hotel']); // Фильтр по статусу if ($request->has('status')) { $query->where('status', $request->status); } // Фильтр по отелю if ($request->has('hotel_id')) { $query->whereHas('roomType.hotel', function ($q) use ($request) { $q->where('id', $request->hotel_id); }); } // Фильтр по дате заезда (от) if ($request->has('from')) { $query->where('check_in', '>=', $request->from); } $query->orderBy('created_at', 'desc'); return response()->json($query->paginate(10)); } public function confirm(Request $request, $id) { $booking = Booking::findOrFail($id); if ($booking->status !== 'pending') { return response()->json(['error' => 'Booking is not in pending status'], 400); } $booking->update([ 'status' => 'confirmed', 'confirmed_at' => now(), ]); return response()->json($booking); } public function cancel(Request $request, $id) { $booking = Booking::findOrFail($id); if ($booking->status === 'cancelled') { return response()->json(['error' => 'Booking is already cancelled'], 400); } $booking->update([ 'status' => 'cancelled', ]); return response()->json($booking); } }