orderQueryService->getOrdersForCustomer( (int) $request->user()->id, ClientOrderFilters::fromArray($request->only(['total_price', 'pending'])) ); return response()->json(['success' => true, 'data' => $orders]); } public function checkServerName(CheckServerNameRequest $request): JsonResponse { $result = $this->orderQueryService->checkServerName($request->string('name')->toString()); return response()->json($result['available'] ? ['available' => true] : $result); } public function getClientOrders(Request $request): JsonResponse { $orders = $this->orderRepository->getOrders((int) $request->user()->id, []); return response()->json([ 'success' => true, 'data' => OrderSummaryResource::collection($orders->getCollection()->load('invoice')), ]); } public function getClientOrderDetail(Request $request, int $id): JsonResponse { $order = $this->orderQueryService->findCustomerOrder((int) $request->user()->id, $id); if (! $order) { return response()->json(['success' => false, 'message' => 'Đơn hàng không tồn tại.'], 404); } return response()->json(['success' => true, 'data' => new OrderDetailResource($order)]); } public function storeOrder(StoreOrderRequest $request): JsonResponse { try { $customer = $request->user(); $data = $request->validated(); $product = \App\Models\Product::where('uuid', $data['product_id'])->first(); if (! $product) { return response()->json(['success' => false, 'message' => 'Sản phẩm không tìm thấy hoặc đã bị xóa.'], 404); } $data['product_id'] = $product->id; $result = $this->orderService->create($data, $customer); $order = $result['order']->load(['orderItems.product', 'invoice', 'customer']); return response()->json([ 'success' => true, 'message' => 'Tạo đơn hàng thành công.', 'notice' => 'Dịch vụ VPS sẽ được khởi tạo trong 5-10 phút sau khi thanh toán.', 'data' => [ 'order' => new OrderDetailResource($order), 'invoice' => new InvoiceDetailResource($result['invoice']->load(['customer', 'order'])), 'items' => OrderItemResource::collection($order->orderItems), ], ], 201); } catch (\Throwable $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 400); } } public function payOrder(int $id, PayOrderRequest $request): JsonResponse { $order = $this->orderRepository->find($id); if (! $order) { return response()->json(['success' => false, 'message' => 'Đơn hàng không tồn tại.'], 404); } if ($order->customer_id !== $request->user()->id) { return response()->json(['success' => false, 'message' => 'Không có quyền truy cập.'], 403); } $this->orderService->pay($order, $request->payment_method); $this->activityLogger->log( event: 'payment', logName: 'Order', description: "Customer {$request->user()->email} thanh toán đơn hàng #{$order->order_num} qua {$request->payment_method}", subject: $order, newValues: ['payment_method' => $request->payment_method, 'total' => $order->total], ); return response()->json(['success' => true, 'message' => 'Thanh toán thành công.']); } public function retryOrderProvisioning(Request $request, int $id): JsonResponse { $order = $this->orderRepository->find($id); if (! $order) { return response()->json(['success' => false, 'message' => 'Đơn hàng không tồn tại.'], 404); } $result = $this->orderQueryService->retryProvisioning($order, (int) $request->user()->id); if (! $result['ok']) { return response()->json(['success' => false, 'message' => $result['message']], $result['code']); } $this->activityLogger->log( event: 'retry_provisioning', logName: 'Order', description: "Customer {$request->user()->email} yêu cầu khởi tạo lại dịch vụ cho đơn hàng #{$order->order_num}", subject: $order, ); return response()->json(['success' => true, 'message' => $result['message']]); } public function getClientInvoices(Request $request): JsonResponse { $invoices = $this->orderQueryService->getCustomerInvoices((int) $request->user()->id); return response()->json(['success' => true, 'data' => InvoiceSummaryResource::collection($invoices)]); } public function getClientInvoiceDetail(Request $request, int $id): JsonResponse { $invoice = $this->orderQueryService->findCustomerInvoice((int) $request->user()->id, $id); if (! $invoice) { return response()->json(['success' => false, 'message' => 'Hóa đơn không tồn tại.'], 404); } return response()->json(['success' => true, 'data' => new InvoiceDetailResource($invoice)]); } public function getClientInvoiceDetailByOrderNum(Request $request, string $orderNumber): JsonResponse { $order = $this->orderQueryService->findCustomerInvoiceByOrderNum((int) $request->user()->id, $orderNumber); if (! $order?->invoice) { return response()->json(['success' => false, 'message' => 'Hóa đơn không tồn tại.'], 404); } return response()->json(['success' => true, 'data' => new InvoiceDetailResource($order->invoice->setRelation('order', $order))]); } public function getClientInvoiceDetailByNumber(Request $request, string $invoiceNumber): JsonResponse { $invoice = $this->orderQueryService->findCustomerInvoiceByNumber((int) $request->user()->id, $invoiceNumber); if (! $invoice) { return response()->json(['success' => false, 'message' => 'Hóa đơn không tồn tại.'], 404); } return response()->json([ 'success' => true, 'data' => new InvoiceDetailResource($invoice), 'payment_url' => url('/client/invoices/' . $invoice->invoice_number . '/payment'), ]); } public function payClientInvoiceByNumber(Request $request, string $invoiceNumber): JsonResponse { $invoice = $this->orderQueryService->findCustomerInvoiceByNumber((int) $request->user()->id, $invoiceNumber); if (! $invoice) { return response()->json(['success' => false, 'message' => 'Hóa đơn không tồn tại.'], 404); } try { $paidInvoice = $this->invoicePaymentService->payWithBalance($invoice, $request->user(), 'balance'); $this->activityLogger->log( event: 'payment', logName: 'Invoice', description: "Customer {$request->user()->email} thanh toán hóa đơn #{$paidInvoice->invoice_number}", subject: $paidInvoice, newValues: ['invoice_number' => $paidInvoice->invoice_number, 'total' => $paidInvoice->total], ); return response()->json([ 'success' => true, 'message' => 'Thanh toán hóa đơn thành công.', 'data' => new InvoiceDetailResource($paidInvoice), ]); } catch (\Throwable $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 422); } } public function getClientServices(Request $request): JsonResponse { $services = $this->orderQueryService->getCustomerServices((int) $request->user()->id); return response()->json(['success' => true, 'data' => ServiceSummaryResource::collection($services)]); } public function getClientServiceDetail(Request $request, string $uuid): JsonResponse { $service = $this->orderQueryService->findCustomerService((int) $request->user()->id, $uuid); if (! $service) { return response()->json(['success' => false, 'message' => 'Không tìm thấy dịch vụ.'], 404); } return response()->json(['success' => true, 'data' => new ServiceDetailResource($service)]); } public function updateClientServiceAutoRenew(Request $request, int $id): JsonResponse { $validated = $request->validate(['auto_renew' => ['required', 'boolean']]); $service = \App\Models\Service::query() ->where('id', $id) ->where('customer_id', $request->user()->id) ->first(); if (! $service) { return response()->json(['success' => false, 'message' => 'Không tìm thấy dịch vụ.'], 404); } $service->update(['auto_renew' => (bool) $validated['auto_renew']]); $this->activityLogger->log( event: 'updated', logName: 'Service', description: "Customer {$request->user()->email} " . ($validated['auto_renew'] ? 'bật' : 'tắt') . " tự động gia hạn dịch vụ #{$service->id}", subject: $service, newValues: ['auto_renew' => (bool) $validated['auto_renew']], ); return response()->json(['success' => true, 'message' => 'Cập nhật tự động gia hạn thành công.', 'data' => ['id' => $service->id, 'auto_renew' => (bool) $service->auto_renew]]); } public function renewService(RenewServiceRequest $request, int $id): JsonResponse { $result = $this->orderQueryService->renewService($id, (int) $request->user()->id, (int) $request->validated()['months']); if (! $result['ok']) { return response()->json(['success' => false, 'message' => $result['message']], $result['code']); } return response()->json(['success' => true, 'message' => $result['message'], 'data' => $result['data']]); } }