get('cart', []); $subtotal = 0; foreach ($cart as $item) { $subtotal += $item['price'] * $item['quantity']; } $shipping = $subtotal > 50 || empty($cart) ? 0.00 : 4.95; $total = $subtotal + $shipping; return view('cart.index', compact('cart', 'subtotal', 'shipping', 'total')); } public function add(Request $request) { $validated = $request->validate([ 'product_id' => 'required|exists:products,id', 'material' => 'required|string', 'color' => 'required|string', 'scale' => 'nullable|string', 'infill' => 'nullable|string', 'quantity' => 'required|integer|min:1|max:50', ]); $product = Product::findOrFail($validated['product_id']); $material = Material::where('code', $validated['material'])->first(); // Prijs berekening inclusief materiaal vermenigvuldiger & schaal $unitPrice = $product->base_price; if ($material) { $unitPrice *= $material->price_multiplier; } // Schaal aanpassing $scale = $validated['scale'] ?? '100%'; if ($scale === '150%') { $unitPrice *= 1.45; } elseif ($scale === '200%') { $unitPrice *= 1.95; } $unitPrice = round($unitPrice, 2); // Unieke sleutel in sessie op basis van product + configuratie $cartKey = md5($product->id.'_'.$validated['material'].'_'.$validated['color'].'_'.$scale); $cart = session()->get('cart', []); if (isset($cart[$cartKey])) { $cart[$cartKey]['quantity'] += (int) $validated['quantity']; } else { $cart[$cartKey] = [ 'id' => $product->id, 'name' => $product->name, 'slug' => $product->slug, 'image_url' => $product->image_url, 'material' => $material ? $material->name : $validated['material'], 'material_code' => $validated['material'], 'color' => $validated['color'], 'scale' => $scale, 'infill' => $validated['infill'] ?? 'Standaard (20%)', 'price' => $unitPrice, 'quantity' => (int) $validated['quantity'], ]; } session()->put('cart', $cart); if ($request->wantsJson()) { return response()->json([ 'success' => true, 'message' => 'Artikel toegevoegd aan je winkelwagen!', 'cartCount' => array_sum(array_column($cart, 'quantity')), ]); } return redirect()->route('cart.index')->with('success', "{$product->name} is toegevoegd aan je winkelwagen!"); } public function addCustom(Request $request) { $validated = $request->validate([ 'model_name' => 'nullable|string|max:255', 'model_url' => 'nullable|url|max:1000', 'model_file' => 'nullable|file|extensions:stl,3mf,obj,step,stp,zip|max:51200', // 50MB 'size' => 'required|in:klein,medium,groot', 'material' => 'required|string', 'color' => 'required|string', 'infill' => 'nullable|string', 'notes' => 'nullable|string|max:1000', 'quantity' => 'required|integer|min:1|max:20', ]); if (! $request->hasFile('model_file') && empty($validated['model_url'])) { return back()->withInput()->with('error', 'Upload een 3D-bestand (.stl, .3mf, .obj, .step) of vul een MakerWorld/Printables link in.'); } $filePath = null; $originalName = null; if ($request->hasFile('model_file')) { $file = $request->file('model_file'); $originalName = $file->getClientOriginalName(); $filePath = $file->store('custom_models', 'public'); } $material = Material::where('code', $validated['material'])->first(); // Basisprijs op basis van formaat $sizePrices = [ 'klein' => 9.95, // tot 8 cm 'medium' => 16.95, // tot 15 cm 'groot' => 24.95, // tot 22 cm ]; $unitPrice = $sizePrices[$validated['size']] ?? 16.95; if ($material) { $unitPrice *= $material->price_multiplier; } $unitPrice = round($unitPrice, 2); $name = ! empty($validated['model_name']) ? $validated['model_name'] : ($originalName ?: 'Eigen 3D Model'); $cartKey = md5('custom_'.($filePath ?: ($validated['model_url'] ?? '')).'_'.$validated['material'].'_'.$validated['color'].'_'.$validated['size']); $cart = session()->get('cart', []); $cart[$cartKey] = [ 'id' => null, 'is_custom' => true, 'name' => 'Custom Print: '.$name, 'slug' => 'custom-3d-print', 'image_url' => 'https://images.unsplash.com/photo-1581092160607-ee22621dd758?auto=format&fit=crop&w=400&q=80', 'material' => $material ? $material->name : $validated['material'], 'material_code' => $validated['material'], 'color' => $validated['color'], 'scale' => ucfirst($validated['size']), 'infill' => $validated['infill'] ?? 'Standaard (20%)', 'price' => $unitPrice, 'quantity' => (int) $validated['quantity'], 'custom_file_path' => $filePath, 'custom_file_name' => $originalName, 'custom_model_url' => $validated['model_url'] ?? null, 'custom_notes' => $validated['notes'] ?? null, ]; session()->put('cart', $cart); return redirect()->route('cart.index')->with('success', "Jouw eigen 3D model '{$name}' is direct toegevoegd aan je winkelwagen!"); } public function update(Request $request) { $validated = $request->validate([ 'key' => 'required|string', 'quantity' => 'required|integer|min:1|max:50', ]); $cart = session()->get('cart', []); if (isset($cart[$validated['key']])) { $cart[$validated['key']]['quantity'] = (int) $validated['quantity']; session()->put('cart', $cart); } return redirect()->route('cart.index')->with('success', 'Winkelwagen bijgewerkt.'); } public function remove($key) { $cart = session()->get('cart', []); if (isset($cart[$key])) { unset($cart[$key]); session()->put('cart', $cart); } return redirect()->route('cart.index')->with('success', 'Artikel verwijderd uit je winkelwagen.'); } public function count() { $cart = session()->get('cart', []); $totalItems = array_sum(array_column($cart, 'quantity')); return response()->json(['count' => $totalItems]); } }