Files
jouwdriedee/app/Http/Controllers/CartController.php
T

203 lines
6.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Material;
use App\Models\Product;
use Illuminate\Http\Request;
class CartController extends Controller
{
public function index()
{
$cart = session()->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|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]);
}
}