cartItems($request); if ($items->isEmpty()) { return redirect()->route('cart.index')->with('status', 'Корзина пустая. Добавьте товары перед оформлением.'); } return view('shop.checkout', [ 'items' => $items, 'total' => $items->sum('subtotal'), 'itemsCount' => $items->sum('quantity'), ]); } public function prepare(Request $request) { $items = $this->cartItems($request); if ($items->isEmpty()) { return redirect()->route('cart.index')->with('status', 'Корзина пустая. Добавьте товары перед оформлением.'); } $validated = $request->validate([ 'customer_name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255'], 'phone' => ['nullable', 'string', 'max:50'], 'address' => ['required', 'string', 'max:500'], 'comment' => ['nullable', 'string', 'max:1000'], ]); $validated['payment_method'] = 'card_transfer'; $request->session()->put(self::CHECKOUT_CUSTOMER_KEY, $validated); return redirect()->route('checkout.payment'); } public function payment(Request $request) { $items = $this->cartItems($request); if ($items->isEmpty()) { return redirect()->route('cart.index')->with('status', 'Корзина пустая. Добавьте товары перед оформлением.'); } $customer = $request->session()->get(self::CHECKOUT_CUSTOMER_KEY); if (!is_array($customer)) { return redirect()->route('checkout.show')->with('status', 'Сначала заполните данные получателя.'); } return view('shop.checkout-payment', [ 'items' => $items, 'total' => $items->sum('subtotal'), 'itemsCount' => $items->sum('quantity'), 'customer' => $customer, ]); } public function store(Request $request) { $items = $this->cartItems($request); if ($items->isEmpty()) { return redirect()->route('cart.index')->with('status', 'Корзина пустая. Добавьте товары перед оформлением.'); } $validated = $request->session()->get(self::CHECKOUT_CUSTOMER_KEY); if (!is_array($validated)) { return redirect()->route('checkout.show')->with('status', 'Сначала заполните данные получателя.'); } $validator = validator($validated, [ 'customer_name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255'], 'phone' => ['nullable', 'string', 'max:50'], 'address' => ['required', 'string', 'max:500'], 'comment' => ['nullable', 'string', 'max:1000'], 'payment_method' => ['required', 'string', Rule::in(['card_transfer'])], ]); $validated = $validator->validate(); $order = DB::transaction(function () use ($request, $items, $validated) { $order = Order::create([ 'user_id' => optional($request->user())->id, 'status' => 'new', 'payment_method' => $validated['payment_method'], 'total' => $items->sum('subtotal'), 'items_count' => $items->sum('quantity'), 'customer_name' => $validated['customer_name'], 'email' => $validated['email'], 'phone' => $validated['phone'] ?? null, 'address' => $validated['address'], 'comment' => $validated['comment'] ?? null, ]); $rows = $items->map(function (array $item) use ($order) { return [ 'order_id' => $order->id, 'product_id' => $item['product']->id, 'name' => $item['product']->name, 'price' => $item['product']->price, 'quantity' => $item['quantity'], 'subtotal' => $item['subtotal'], 'created_at' => now(), 'updated_at' => now(), ]; })->all(); OrderItem::insert($rows); return $order; }); $request->session()->forget('cart'); $request->session()->forget(self::CHECKOUT_CUSTOMER_KEY); return redirect()->route('checkout.success', $order); } public function success(Order $order) { return view('shop.checkout-success', [ 'order' => $order, ]); } private function cartItems(Request $request) { $cart = (array) $request->session()->get('cart', []); $products = Product::query() ->whereIn('id', array_keys($cart)) ->where('is_active', true) ->get() ->keyBy('id'); return collect($cart) ->map(function ($quantity, $productId) use ($products) { $product = $products->get((int) $productId); if (!$product) { return null; } $qty = max(1, min((int) $quantity, (int) $product->stock)); if ($qty < 1) { return null; } return [ 'product' => $product, 'quantity' => $qty, 'subtotal' => (float) $product->price * $qty, ]; }) ->filter() ->values(); } }