81 lines
2.5 KiB
PHP
81 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use App\Models\Customer;
|
|
use App\Models\Instance;
|
|
use LivewireUI\Modal\ModalComponent;
|
|
|
|
/**
|
|
* Cancel the customer's package (R5). Per the founder's decision: effective at
|
|
* the end of the billing term, irreversible once confirmed; at term end the
|
|
* customer receives a finished data export, then the instance is deprovisioned
|
|
* (both mocked for now). Requires typing the instance subdomain to confirm.
|
|
*/
|
|
class ConfirmCancelPackage extends ModalComponent
|
|
{
|
|
public string $confirmName = '';
|
|
|
|
public function cancelPackage()
|
|
{
|
|
$customer = $this->customer();
|
|
$instance = $customer?->instances()->latest('id')->first();
|
|
|
|
// Only an active package can be cancelled — never resurrect an already
|
|
// cancelled/deprovisioned/scheduled instance.
|
|
if ($instance === null || $instance->status !== 'active') {
|
|
return $this->redirectRoute('settings', navigate: true);
|
|
}
|
|
|
|
// Typed confirmation must match the instance subdomain.
|
|
if (trim($this->confirmName) !== (string) $instance->subdomain) {
|
|
$this->addError('confirmName', __('settings.cancel_mismatch'));
|
|
|
|
return;
|
|
}
|
|
|
|
$instance->update([
|
|
'status' => 'cancellation_scheduled',
|
|
'cancel_requested_at' => now(),
|
|
'service_ends_at' => $this->currentPeriodEnd($instance),
|
|
]);
|
|
|
|
return $this->redirectRoute('settings', navigate: true);
|
|
}
|
|
|
|
/**
|
|
* End of the current monthly billing period, anchored on the subscription
|
|
* start (the order date) rather than assuming calendar-month billing.
|
|
*/
|
|
private function currentPeriodEnd(Instance $instance): \Illuminate\Support\Carbon
|
|
{
|
|
$start = $instance->order?->created_at ?? $instance->created_at ?? now();
|
|
$end = $start->copy();
|
|
while ($end->lessThanOrEqualTo(now())) {
|
|
$end->addMonthNoOverflow();
|
|
}
|
|
|
|
return $end;
|
|
}
|
|
|
|
private function customer(): ?Customer
|
|
{
|
|
$user = auth()->user();
|
|
if (! $user) {
|
|
return null;
|
|
}
|
|
|
|
return Customer::query()->where('user_id', $user->id)->first()
|
|
?? Customer::query()->where('email', $user->email)->first();
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$instance = $this->customer()?->instances()->latest('id')->first();
|
|
|
|
return view('livewire.confirm-cancel-package', [
|
|
'subdomain' => $instance?->subdomain ?? '',
|
|
]);
|
|
}
|
|
}
|