cart->count() === 0) { return redirect()->route('cart.index')->with('error', 'Ihr Warenkorb ist leer.'); } $subtotal = $this->cart->subtotal(); $country = session('checkout_country', 'DE'); $shippingRate = ShippingRate::forCart($subtotal, $country); $shippingCost = $shippingRate ? $shippingRate->getCostForTotal($subtotal) : 0; $discount = $this->getCouponDiscount($subtotal); $total = max(0, $subtotal - $discount) + $shippingCost; $userAddresses = auth()->user()?->addresses ?? collect(); $couponCode = session('coupon_code'); return view('shop.checkout.index', compact('subtotal', 'shippingCost', 'total', 'userAddresses', 'discount', 'couponCode')); } public function applyCoupon(Request $request) { $code = trim($request->input('coupon_code', '')); if (!$code) { return back()->with('coupon_error', 'Bitte Gutscheincode eingeben.'); } $coupon = Coupon::findValid($code); if (!$coupon) { return back()->with('coupon_error', 'Gutscheincode ungültig oder abgelaufen.'); } $subtotal = $this->cart->subtotal(); if ($coupon->min_order_value && $subtotal < $coupon->min_order_value) { return back()->with('coupon_error', 'Mindestbestellwert von ' . number_format($coupon->min_order_value, 2, ',', '.') . ' € nicht erreicht.'); } session(['coupon_code' => $coupon->code]); return back()->with('coupon_success', 'Gutschein "' . $coupon->code . '" angewendet!'); } public function removeCoupon() { session()->forget('coupon_code'); return back()->with('coupon_success', 'Gutschein entfernt.'); } public function shippingCost(Request $request) { $country = strtoupper($request->input('country', 'DE')); session(['checkout_country' => $country]); $subtotal = $this->cart->subtotal(); $shippingRate = ShippingRate::forCart($subtotal, $country); $cost = $shippingRate ? $shippingRate->getCostForTotal($subtotal) : 0; return response()->json(['cost' => $cost, 'formatted' => number_format($cost, 2, ',', '.') . ' €']); } public function storeAddress(Request $request) { $rules = [ 'billing.first_name' => 'required|string|max:100', 'billing.last_name' => 'required|string|max:100', 'billing.street' => 'required|string|max:255', 'billing.zip' => 'required|string|max:10', 'billing.city' => 'required|string|max:100', 'billing.country' => 'required|string|max:2', 'payment_method' => 'required|in:prepayment,invoice', 'agb' => 'accepted', ]; if (!auth()->check()) { $rules['email'] = 'required|email'; } if ($request->input('shipping_same') !== '1') { $rules['shipping.first_name'] = 'required|string|max:100'; $rules['shipping.last_name'] = 'required|string|max:100'; $rules['shipping.street'] = 'required|string|max:255'; $rules['shipping.zip'] = 'required|string|max:10'; $rules['shipping.city'] = 'required|string|max:100'; $rules['shipping.country'] = 'required|string|max:2'; } $data = $request->validate($rules); if ($request->input('shipping_same') === '1') { $data['shipping'] = $data['billing']; } $data['email'] = $request->input('email'); session(['checkout_data' => $data]); if ($data['payment_method'] === 'paypal') { return redirect()->route('paypal.redirect'); } return redirect()->route('checkout.confirm'); } public function payment() { return redirect()->route('checkout.index'); } public function confirm(Request $request) { $checkoutData = session('checkout_data'); if (!$checkoutData || $this->cart->count() === 0) { return redirect()->route('checkout.index'); } if ($request->isMethod('get')) { $items = $this->cart->get(); $subtotal = $this->cart->subtotal(); $country = $checkoutData['shipping']['country'] ?? $checkoutData['billing']['country'] ?? 'DE'; $shippingRate = ShippingRate::forCart($subtotal, $country); $shippingCost = $shippingRate ? $shippingRate->getCostForTotal($subtotal) : 0; $discount = $this->getCouponDiscount($subtotal); $total = max(0, $subtotal - $discount) + $shippingCost; $couponCode = session('coupon_code'); return view('shop.checkout.confirm', compact('checkoutData', 'items', 'subtotal', 'shippingCost', 'total', 'discount', 'couponCode')); } $order = $this->orderService->createFromSession( $checkoutData, $checkoutData['payment_method'] ); session()->forget(['checkout_data', 'checkout_country']); return redirect()->route('checkout.thankyou', $order->order_number); } public function thankyou(string $order) { $order = \App\Models\Order::where('order_number', $order)->firstOrFail(); return view('shop.checkout.thankyou', compact('order')); } private function getCouponDiscount(float $subtotal): float { if ($code = session('coupon_code')) { $coupon = Coupon::findValid($code); if ($coupon) { return $coupon->calcDiscount($subtotal); } } return 0; } }