namespace App\Http\Controllers\Web; use App\Http\Controllers\Controller; use App\Http\Requests\Order\CreateOrderRequest; use App\Models\Category; use App\Models\Service; use App\Models\Order; use App\Services\Order\OrderService; use App\Services\Order\OrderValidator; use App\Services\Wallet\WalletService; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class OrderController extends Controller { protected $orderService; protected $orderValidator; protected $walletService; public function __construct( OrderService $orderService, OrderValidator $orderValidator, WalletService $walletService ) { $this->orderService = $orderService; $this->orderValidator = $orderValidator; $this->walletService = $walletService; } // Show order page public function index(Request $request) { $user = auth()->user(); $query = $user->orders()->with(['service', 'service.category']); // Filters if ($request->has('status') && $request->status != 'all') { $query->where('status', $request->status); } if ($request->has('search')) { $query->where(function($q) use ($request) { $q->where('order_id', 'like', '%' . $request->search . '%') ->orWhere('link', 'like', '%' . $request->search . '%'); }); } $orders = $query->latest()->paginate(15); $stats = [ 'total' => $user->orders()->count(), 'completed' => $user->orders()->where('status', 'completed')->count(), 'processing' => $user->orders()->whereIn('status', ['pending', 'processing'])->count(), 'total_spent' => $user->total_spent, ]; return view('web.dashboard.orders.index', compact('orders', 'stats')); } // Show create order form public function create() { $user = auth()->user(); $categories = Category::where('status', 'active') ->with(['services' => function($query) { $query->where('status', 'active') ->orderBy('sort_order'); }]) ->orderBy('sort_order') ->get(); $walletBalance = $user->wallet?->available_balance ?? 0; return view('web.dashboard.orders.create', compact('categories', 'walletBalance')); } // Get service details (AJAX) public function getServiceDetails(Service $service) { if ($service->status !== 'active') { return response()->json(['error' => 'Service not available'], 404); } return response()->json([ 'id' => $service->id, 'name' => $service->name, 'price' => $service->price, 'min' => $service->min_order, 'max' => $service->max_order, 'description' => $service->description, 'required_fields' => $service->required_fields, ]); } // Calculate price (AJAX) public function calculatePrice(Request $request) { $request->validate([ 'service_id' => 'required|exists:services,id', 'quantity' => 'required|integer|min:1', ]); $service = Service::findOrFail($request->service_id); $quantity = $request->quantity; // Validate quantity range if ($quantity < $service->min_order) { return response()->json([ 'error' => 'Minimum order quantity is ' . $service->min_order ], 422); } if ($service->max_order && $quantity > $service->max_order) { return response()->json([ 'error' => 'Maximum order quantity is ' . $service->max_order ], 422); } $price = $service->price * $quantity; return response()->json([ 'price' => $price, 'formatted' => number_format($price, 2), ]); } // Store order public function store(CreateOrderRequest $request) { $user = auth()->user(); try { DB::beginTransaction(); // Validate order $this->orderValidator->validate($request->validated(), $user); // Create order $order = $this->orderService->createOrder($user, $request->validated()); // Process payment $this->walletService->processOrderPayment($user, $order); DB::commit(); // Process order (queue) $this->orderService->processOrder($order); return redirect()->route('orders.show', $order->order_id) ->with('success', 'Order placed successfully!'); } catch (\Exception $e) { DB::rollBack(); return back()->withInput() ->withErrors(['error' => $e->getMessage()]); } } // Show order details public function show($orderId) { $user = auth()->user(); $order = $user->orders() ->with(['service', 'service.category', 'refills', 'logs']) ->where('order_id', $orderId) ->firstOrFail(); return view('web.dashboard.orders.show', compact('order')); } // Request refill public function requestRefill(Order $order) { $user = auth()->user(); if ($order->user_id !== $user->id) { abort(403); } if (!$order->service->refill_possible) { return back()->with('error', 'Refill is not available for this service.'); } if ($order->status !== 'completed') { return back()->with('error', 'Order must be completed to request a refill.'); } try { $refill = $this->orderService->requestRefill($order); return back()->with('success', 'Refill requested successfully. Refill ID: ' . $refill->refill_id); } catch (\Exception $e) { return back()->with('error', $e->getMessage()); } } // Cancel order public function cancel(Order $order) { $user = auth()->user(); if ($order->user_id !== $user->id) { abort(403); } if (!$order->service->cancel_possible) { return back()->with('error', 'Cancellation is not available for this service.'); } if (!in_array($order->status, ['pending', 'processing'])) { return back()->with('error', 'Order cannot be cancelled at this stage.'); } try { $this->orderService->cancelOrder($order); return back()->with('success', 'Order cancelled successfully. Refund will be processed.'); } catch (\Exception $e) { return back()->with('error', $e->getMessage()); } } // Download invoice public function downloadInvoice(Order $order) { $user = auth()->user(); if ($order->user_id !== $user->id) { abort(403); } return $this->orderService->generateInvoice($order); } // Order statistics public function statistics() { $user = auth()->user(); $stats = [ 'daily' => $user->orders() ->whereDate('created_at', today()) ->count(), 'weekly' => $user->orders() ->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]) ->count(), 'monthly' => $user->orders() ->whereMonth('created_at', now()->month) ->count(), 'total' => $user->orders()->count(), 'spending_today' => $user->orders() ->whereDate('created_at', today()) ->where('status', '!=', 'cancelled') ->sum('price'), 'spending_month' => $user->orders() ->whereMonth('created_at', now()->month) ->where('status', '!=', 'cancelled') ->sum('price'), ]; $recentActivity = $user->orders() ->with('service') ->latest() ->limit(10) ->get(); return view('web.dashboard.orders.statistics', compact('stats', 'recentActivity')); } }