CluPilotCloud/app/Livewire/ConfirmCloseAccount.php

66 lines
1.9 KiB
PHP

<?php
namespace App\Livewire;
use App\Livewire\Concerns\ResolvesCustomer;
use App\Models\Customer;
use LivewireUI\Modal\ModalComponent;
/**
* Close the whole CluPilot account (R5). Guarded: only allowed when no active
* package remains — an active subscription must be cancelled first. Sets
* closed_at; financial records are retained. Requires typing "LOESCHEN".
*/
class ConfirmCloseAccount extends ModalComponent
{
use ResolvesCustomer;
public string $confirmWord = '';
public function closeAccount()
{
$customer = $this->customer();
// No customer behind this login (e.g. an operator account) — say so
// instead of leaving the button looking broken.
if ($customer === null) {
$this->addError('confirmWord', __('dashboard.no_customer_action'));
return null;
}
if ($this->hasActivePackage($customer)) {
$this->addError('confirmWord', __('settings.close_blocked'));
return;
}
if (mb_strtoupper(trim($this->confirmWord)) !== __('settings.close_keyword')) {
$this->addError('confirmWord', __('settings.close_mismatch'));
return;
}
$customer->update(['closed_at' => now(), 'status' => 'closed']);
return $this->redirectRoute('settings', navigate: true);
}
private function hasActivePackage(Customer $customer): bool
{
// Only genuinely-live packages block closure — a failed/cancelled/
// deprovisioned instance does not retain a service.
return $customer->instances()
->whereIn('status', ['active', 'provisioning', 'cancellation_scheduled'])
->exists();
}
public function render()
{
$customer = $this->customer();
return view('livewire.confirm-close-account', [
'blocked' => $customer !== null && $this->hasActivePackage($customer),
]);
}
}