provision($plesk, $servers, $failure); } catch (Throwable $e) { $error = $e->getMessage(); } if ($error !== null) { $failure->handle($this->item, $error); } } private function provision(PleskHostingService $plesk, HostingServerSelector $servers, HostingProvisionFailure $failure): ?string { $service = $this->item->service()->first(); $domainName = $this->item->server_name; if (! $service || ! $domainName) { return 'Không tìm thấy dịch vụ hoặc tên miền của đơn hàng.'; } $servicePlanId = $this->item->product?->service_plan_id; $servicePlan = $servicePlanId ? ServicePlan::with('plesk')->find($servicePlanId) : null; $hostingPlan = $servicePlan?->plesk?->plesk_plan_name; Log::channel('Custom')->info('ProvisionHostingAccountJob resolved service plan', [ 'order_item_id' => $this->item->id, 'product_id' => $this->item->product_id, 'product_name' => $this->item->product?->name, 'service_plan_id' => $servicePlanId, 'plesk_plan_name' => $hostingPlan, ]); if (! $hostingPlan) { return 'Sản phẩm chưa gắn gói Plesk (service_plan_plesk).'; } ServiceProvisionLog::record($service, 'provision_started', 'Bắt đầu khởi tạo hosting', ['domain' => $domainName, 'plesk_plan' => $hostingPlan]); $invoiceId = Invoice::where('order_id', $this->item->order_id)->where('invoice_type', 1)->orderBy('id')->value('id'); $triedServerIds = []; $lastError = null; while ($server = $servers->pick($servicePlan, $triedServerIds)) { $triedServerIds[] = $server->id; $result = $plesk->provision([ 'customer_id' => $this->item->order->customer_id, 'service_id' => $service->id, 'dns_manager_server_id' => $server->id, 'domain_name' => $domainName, 'hosting_plan' => $hostingPlan, 'invoice_id' => $invoiceId, ]); if (! $result['error']) { $service->update(['status' => 'active']); ServiceProvisionLog::record($service, 'provision_completed', 'Khởi tạo hoàn tất — dịch vụ đã hoạt động', ['server_id' => $server->id]); return null; } $lastError = $result['message'] ?? 'Plesk trả về lỗi không rõ.'; $servers->forget($server); if ($servers->isHealthy($server)) { return $lastError; } $failure->serverFailedOver($this->item, $server, $lastError); } return $lastError === null ? 'Gói hosting không có server Plesk nào đang hoạt động.' : "Tất cả server Plesk của gói đều lỗi. Lỗi cuối: {$lastError}"; } }