commit 12.01

This commit is contained in:
Владимир
2026-01-12 14:25:15 +00:00
parent 36084ba590
commit ae5ab2554b
26 changed files with 1116 additions and 1083 deletions

View File

@@ -2,165 +2,112 @@
namespace App\Http\Controllers;
use App\Models\Booking;
use App\Models\Services;
use App\Models\EmployeeAvailability;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Models\Booking;
use App\Models\Service;
use App\Models\User;
class BookingsController extends Controller
{
public function store(Request $request)
{
$request->validate([
$validated = $request->validate([
'service_id' => 'required|exists:services,id',
'employee_id' => 'required|exists:users,id',
'date' => 'required|date',
'starttime' => 'required'
'start_time' => 'required|date_format:H:i:s'
]);
$clientId = auth()->id();
if (!$clientId) {
return response()->json(['error' => 'Авторизация обязательна'], 401);
}
// Получаем длительность услуги
$service = Service::findOrFail($validated['service_id']);
$duration = $service->duration_minutes;
$service = Services::where('id', $request->service_id)
->where('isactive', true)
->first();
if (!$service) {
return response()->json(['error' => 'Услуга неактивна или не найдена'], 400);
}
// Вычисляем end_time
$start = new \DateTime($validated['start_time']);
$end = clone $start;
$end->modify("+$duration minutes");
$end_time = $end->format('H:i:s');
$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'])
// Проверяем, свободен ли слот
$conflict = Booking::where('employee_id', $validated['employee_id'])
->where('booking_date', $validated['date'])
->where('start_time', '<', $end_time)
->where('end_time', '>', $validated['start_time'])
->exists();
if ($bookingExists) {
return response()->json(['error' => 'Слот уже забронирован'], 400);
if ($conflict) {
return response()->json(['message' => 'Слот занят'], 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,
'booking_number' => 'CL-' . date('Y') . '-' . str_pad(Booking::count() + 1, 4, '0', STR_PAD_LEFT),
'client_id' => auth()->id(),
'employee_id' => $validated['employee_id'],
'service_id' => $validated['service_id'],
'booking_date' => $validated['date'],
'start_time' => $validated['start_time'],
'end_time' => $end_time,
'status' => 'confirmed'
]);
return response()->json([
'booking' => $booking,
'message' => 'Бронирование создано №' . $bookingNumber
], 201);
return response()->json($booking, 201);
}
public function cancel(Request $request, $id)
public function clientIndex()
{
$booking = Booking::findOrFail($id);
if ($booking->client_id != auth()->id()) {
return response()->json(['error' => 'Можете отменить только свою бронь'], 403);
}
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
]);
}
public function adminCancel(Request $request, $id)
{
$booking = Booking::findOrFail($id);
if (!auth()->user()->isEmployeeOrAdmin()) {
return response()->json(['error' => 'Доступ только для админов/сотрудников'], 403);
}
$booking->update([
'status' => 'cancelled',
'cancelledby' => 'admin',
'cancelreason' => $request->reason ?? null
]);
return response()->json([
'message' => 'Бронь отменена администратором',
'booking' => $booking
]);
}
public function clientIndex(Request $request)
{
$clientId = auth()->id();
$query = Booking::where('client_id', $clientId);
if ($request->date) {
$query->where('bookingdate', $request->date);
}
if ($request->status) {
$query->where('status', $request->status);
}
$bookings = $query->with(['service', 'employee'])
->orderBy('bookingdate', 'desc')
->orderBy('starttime', 'asc')
->get();
$bookings = Booking::where('client_id', auth()->id())->get();
return response()->json($bookings);
}
public function adminIndex(Request $request)
// adminIndex
public function adminIndex()
{
if (!auth()->user()->isEmployeeOrAdmin()) {
return response()->json(['error' => 'Доступ запрещен'], 403);
}
$query = Booking::with(['service', 'client', 'employee']);
if ($request->date) {
$query->where('bookingdate', $request->date);
}
if ($request->status) {
$query->where('status', $request->status);
}
if ($request->employee_id) {
$query->where('employee_id', $request->employee_id);
}
$bookings = $query->orderBy('bookingdate', 'desc')
->orderBy('starttime', 'asc')
$bookings = Booking::with(['client', 'employee', 'service'])
->orderBy('booking_date', 'desc')
->get();
return response()->json($bookings);
}
public function cancel($id)
{
$booking = Booking::findOrFail($id);
if ($booking->client_id !== auth()->id()) {
return response()->json(['message' => 'Нет прав'], 403);
}
$booking->update([
'status' => 'cancelled',
'cancelled_by' => 'client',
'cancel_reason' => request('reason')
]);
return response()->json(['message' => 'Бронь отменена']);
}
// adminCancel
public function adminCancel($id)
{
$booking = Booking::findOrFail($id);
$booking->update([
'status' => 'cancelled',
'cancelled_by' => 'admin',
'cancel_reason' => request('reason')
]);
return response()->json(['message' => 'Бронь отменена администратором']);
}
// Назначение сотрудника
public function assignEmployee(Request $request, $id)
{
$request->validate(['employee_id' => 'required|exists:users,id']);
$booking = Booking::findOrFail($id);
$booking->employee_id = $request->employee_id;
$booking->save();
return response()->json($booking);
}
}