validate([ 'service_id' => 'required|exists:services,id', 'employee_id' => 'required|exists:users,id', 'date' => 'required|date', 'starttime' => 'required' ]); $clientId = auth()->id(); if (!$clientId) { return response()->json(['error' => 'Авторизация обязательна'], 401); } // Проверить активную услугу $service = Services::where('id', $request->service_id) ->where('isactive', true) ->first(); if (!$service) { return response()->json(['error' => 'Услуга неактивна или не найдена'], 400); } $durationMinutes = $service->durationminutes; $endtime = date('H:i:s', strtotime($request->starttime . " +{$durationMinutes} minutes")); // Проверить доступность сотрудника $availability = EmployeeAvailability::where('employee_id', $request->employee_id) ->where('date', $request->date) ->where('starttime', '<=', $request->starttime) ->where('endtime', '>=', $endtime) ->where('isavailable', true) ->first(); if (!$availability) { return response()->json(['error' => 'Сотрудник недоступен в это время'], 400); } // Проверить уникальность слота $bookingExists = Booking::where('employee_id', $request->employee_id) ->where('bookingdate', $request->date) ->where('starttime', $request->starttime) ->whereIn('status', ['confirmed', 'completed']) ->exists(); if ($bookingExists) { return response()->json(['error' => 'Слот уже забронирован'], 400); } // Создать бронь $bookingNumber = 'CL-' . date('Y') . '-' . str_pad(Booking::count() + 1, 4, '0', STR_PAD_LEFT); $booking = Booking::create([ 'bookingnumber' => $bookingNumber, 'client_id' => $clientId, 'employee_id' => $request->employee_id, 'service_id' => $request->service_id, 'bookingdate' => $request->date, 'starttime' => $request->starttime, 'endtime' => $endtime, 'status' => 'confirmed' ]); return response()->json([ 'booking' => $booking, 'message' => 'Бронирование создано №' . $bookingNumber ], 201); } // POST api/bookings/{id}/cancel - отмена клиентом public function cancel(Request $request, $id) { $booking = Booking::findOrFail($id); // Только автор брони может отменить if ($booking->client_id != auth()->id()) { return response()->json(['error' => 'Можете отменить только свою бронь'], 403); } // Только confirmed брони if ($booking->status != 'confirmed') { return response()->json(['error' => 'Можно отменить только подтвержденные'], 400); } $booking->update([ 'status' => 'cancelled', 'cancelledby' => 'client', 'cancelreason' => $request->reason ?? null ]); return response()->json([ 'message' => 'Бронь отменена', 'booking' => $booking ]); } }