feat(refunds): persist and apply refund configuration per event

This commit is contained in:
2026-09-30 15:31:54 -03:00
parent a770d435eb
commit 5a0ce08adb
7 changed files with 77 additions and 16 deletions

View File

@@ -9,6 +9,7 @@ use App\Domains\Commerce\Purchase\Models\PurchaseItem;
use App\Domains\Commerce\Purchase\Services\PurchaseRefundSummaryService;
use App\Domains\Core\Auth\Models\User;
use App\Domains\Core\Tenant\Models\Tenant;
use App\Domains\Ticketing\Event\Models\Event;
use App\Domains\Ticketing\Ticket\Models\Ticket;
use App\Domains\Ticketing\Ticket\Models\TicketRefund;
use Illuminate\Database\Eloquent\Builder;
@@ -23,6 +24,7 @@ class AdminAppTicketService
...TicketValidityResolver::RELATIONS,
...TicketPresentationResolver::RELATIONS,
'tenant',
'event',
'user',
'scannerUser',
'sourceCatalogItem.category',
@@ -145,19 +147,20 @@ class AdminAppTicketService
]);
}
$configuration = $ticket->event_id === null ? $tenant : $ticket->event;
$unitPrice = (float) $purchaseItem->precio_unitario;
$itemTotal = (float) $purchaseItem->total;
$itemRefundedAmount = $this->refundedAmountForPurchaseItem($purchaseItem);
$remainingItemAmount = max(0.0, round($itemTotal - $itemRefundedAmount, 2));
$total = null;
if ($tenant->allow_refund() && $tenant->allow_ticket_total_refund && $unitPrice <= $remainingItemAmount) {
if ($configuration->allow_refund() && $configuration->allow_ticket_total_refund && $unitPrice <= $remainingItemAmount) {
$total = number_format($unitPrice, 2, '.', '');
}
$partial = null;
if ($tenant->allow_refund() && $tenant->allow_partial_refund()) {
$partialAmount = $this->refundAmount($purchaseItem, $tenant, 'partial');
if ($configuration->allow_refund() && $configuration->allow_partial_refund()) {
$partialAmount = $this->refundAmount($purchaseItem, $configuration, 'partial');
if ($partialAmount <= $remainingItemAmount) {
$partial = number_format($partialAmount, 2, '.', '');
}
@@ -175,14 +178,15 @@ class AdminAppTicketService
string $refundType,
?User $createdBy = null,
): Ticket {
$this->ensureRefundIsAllowed($tenant, $refundType);
return DB::transaction(function () use ($tenant, $ticketId, $refundType, $createdBy): Ticket {
$ticket = Ticket::query()
->where('tenant_code', $tenant->codigo)
->lockForUpdate()
->findOrFail($ticketId);
$configuration = $ticket->event_id === null ? $tenant : $ticket->event;
$this->ensureRefundIsAllowed($configuration, $refundType);
if (! $ticket->can_refund()) {
if ($ticket->status !== Ticket::STATUS_ACTIVE) {
throw ValidationException::withMessages([
@@ -205,7 +209,7 @@ class AdminAppTicketService
]);
}
$refundAmount = $this->refundAmount($purchaseItem, $tenant, $refundType);
$refundAmount = $this->refundAmount($purchaseItem, $configuration, $refundType);
$refundedAmount = round(
$this->refundedAmountForPurchaseItem($purchaseItem) + $refundAmount,
2,
@@ -286,7 +290,7 @@ class AdminAppTicketService
->sum('amount'), 2);
}
private function ensureRefundIsAllowed(Tenant $tenant, string $refundType): void
private function ensureRefundIsAllowed(Tenant|Event $tenant, string $refundType): void
{
$isAllowed = match ($refundType) {
TicketRefund::TYPE_PARTIAL => $tenant->allow_refund() && $tenant->allow_partial_refund(),
@@ -300,7 +304,7 @@ class AdminAppTicketService
}
}
private function refundAmount(PurchaseItem $purchaseItem, Tenant $tenant, string $refundType): float
private function refundAmount(PurchaseItem $purchaseItem, Tenant|Event $tenant, string $refundType): float
{
$ticketAmount = (float) $purchaseItem->precio_unitario;