203 lines
6.9 KiB
PHP
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]);
|
|
}
|
|
}
|