Initial commit
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
ssww23
2026-03-10 00:55:37 +03:00
parent fc0f28d830
commit 93a655235a
155 changed files with 24768 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
<?php
namespace App\Http\Controllers\Shop;
use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class CheckoutController extends Controller
{
private const CHECKOUT_CUSTOMER_KEY = 'checkout.customer';
public function show(Request $request)
{
$items = $this->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();
}
}