cart->get(); $subtotal = $this->cart->subtotal(); $shippingRate = ShippingRate::forCart($subtotal); $shippingCost = $shippingRate ? $shippingRate->getCostForTotal($subtotal) : 0; $taxTotal = array_sum(array_map(function ($item) { $net = $item['price'] / (1 + $item['tax_rate'] / 100); return round(($item['price'] - $net) * $item['qty'], 2); }, $items)); $order = Order::create([ 'order_number' => Order::generateOrderNumber(), 'user_id' => auth()->id(), 'guest_email' => auth()->check() ? null : ($addressData['email'] ?? null), 'status' => 'new', 'payment_method' => $paymentMethod, 'subtotal' => $subtotal, 'tax_total' => $taxTotal, 'shipping_cost' => $shippingCost, 'total' => $subtotal + $shippingCost, ]); foreach ($items as $item) { OrderItem::create([ 'order_id' => $order->id, 'product_variant_id'=> $item['variant_id'], 'product_name' => $item['product_name'], 'variant_label' => $item['variant_label'], 'quantity' => $item['qty'], 'unit_price' => $item['price'], 'tax_rate' => $item['tax_rate'], ]); // Bestand reduzieren — nur wenn track_stock aktiv $variant = ProductVariant::with('product')->find($item['variant_id']); if ($variant && $variant->product->track_stock) { $variant->decrement('stock', $item['qty']); } } foreach (['billing', 'shipping'] as $type) { $src = $addressData[$type] ?? $addressData['billing']; OrderAddress::create(array_merge($src, ['order_id' => $order->id, 'type' => $type])); } $this->cart->clear(); Mail::to($order->guest_email ?? $order->user?->email)->send(new OrderConfirmationMail($order)); return $order; } public function updateStatus(Order $order, string $newStatus, ?string $trackingCode = null): void { $order->status = $newStatus; if ($newStatus === 'payment_received' && !$order->paid_at) { $order->paid_at = now(); } if ($trackingCode) { $order->tracking_code = $trackingCode; } $order->save(); if ($newStatus === 'shipped') { $email = $order->guest_email ?? $order->user?->email; if ($email) { Mail::to($email)->send(new OrderShippedMail($order)); } } } }