CluPilotCloud/app/Livewire/ConfirmCancelAddon.php

69 lines
2.3 KiB
PHP

<?php
namespace App\Livewire;
use App\Livewire\Concerns\ResolvesCustomer;
use App\Models\SubscriptionAddon;
use App\Services\Billing\AddonCatalogue;
use LivewireUI\Modal\ModalComponent;
/**
* Confirmation before a booked module is cancelled (R23).
*
* A recurring charge stopping is a consequence worth one dialog: the module
* keeps running to the end of the term that is already paid for, earns no
* credit, and then goes — and for a storage pack, "then goes" is a hundred
* gigabytes the customer has to have moved off by that date. That is a sentence
* somebody should read before, not after.
*
* The date is worked out here from the contract rather than passed in from the
* card, for the same reason ConfirmBookStorage clamps its own number: a modal is
* opened with arguments from markup, and a dialog must not be able to promise
* something the action behind it would not do.
*
* No mutation here. Billing::cancelAddon() keeps the work, the ownership check
* and the customer resolution it already has; this only says yes.
*/
class ConfirmCancelAddon extends ModalComponent
{
use ResolvesCustomer;
public string $addonKey = '';
public function mount(string $key): void
{
$this->addonKey = $key;
}
public function proceed(): void
{
$this->dispatch('addon-cancel-confirmed', key: $this->addonKey);
$this->closeModal();
}
public function render()
{
$customer = $this->customer();
// The module's own bookings, on this customer's contract and nobody
// else's — the same scoping the action uses, because a dialog that
// described a stranger's booking would be an information leak in the
// shape of a date.
$endsAt = $customer === null
? null
: SubscriptionAddon::query()
->whereHas('subscription', fn ($q) => $q->where('customer_id', $customer->id))
->where('addon_key', $this->addonKey)
->active()
->get()
->map(fn (SubscriptionAddon $addon) => $addon->subscription?->current_period_end)
->filter()
->min();
return view('livewire.confirm-cancel-addon', [
'moduleName' => app(AddonCatalogue::class)->name($this->addonKey),
'endsAt' => $endsAt,
]);
}
}