user(); if ($user === null) { return null; } $customer = Customer::query()->where('email', $user->email)->first(); if ($customer === null) { return null; } // The BUILD, not every run against the order. An address re-apply runs // on the same subject and would light this card up with "Ihre Cloud // wird bereitgestellt" over a router file being rewritten — on a cloud // that has been running for months. return ProvisioningRun::query() ->where('subject_type', Order::class) ->where('pipeline', 'customer') ->whereIn('subject_id', $customer->orders()->select('id')) ->latest('id') ->first(); } public function render() { $run = $this->currentRun(); // Show the card while provisioning is in flight OR terminally failed; but // only POLL while it can still change (terminal failed must not poll forever). $show = $run !== null && $run->status !== ProvisioningRun::STATUS_COMPLETED; $polling = $run !== null && in_array($run->status, [ ProvisioningRun::STATUS_PENDING, ProvisioningRun::STATUS_RUNNING, ProvisioningRun::STATUS_WAITING, ], true); return view('livewire.customer-provisioning', [ 'active' => $show, 'polling' => $polling, 'failed' => $run?->status === ProvisioningRun::STATUS_FAILED, // Waiting for a MACHINE, not for a step to finish. A paid order // that no host has room for is parked rather than failed — the // customer has paid, and "we have to buy a server first" is a // purchasing decision, not a fault of theirs. Recognised by where // the run is standing, the same way the console's queue finds it. 'parked' => $run !== null && app(HostCapacity::class)->isParked($run), 'steps' => $show ? $this->buildRunSteps($run) : [], ]); } }