Commit adffa599 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Add refund button on invoice show page for each confirmed payment

Users with 'refunds.initiate' permission see a "استرداد" button next to
each confirmed inbound payment. Confirms before executing.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent e903c1d9
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
use App\Domain\Financial\Models\Invoice; use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Services\InvoiceService; use App\Domain\Financial\Services\InvoiceService;
use App\Domain\Financial\Services\PaymentService; use App\Domain\Financial\Services\PaymentService;
use App\Domain\Financial\Services\RefundService;
use App\Domain\Shared\Exceptions\DomainException; use App\Domain\Shared\Exceptions\DomainException;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Computed; use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout; use Livewire\Attributes\Layout;
use Livewire\Attributes\Title; use Livewire\Attributes\Title;
...@@ -164,6 +166,32 @@ public function canRecordPayment(): bool ...@@ -164,6 +166,32 @@ public function canRecordPayment(): bool
&& !in_array($this->invoice->status, [InvoiceStatus::Cancelled, InvoiceStatus::Refunded]); && !in_array($this->invoice->status, [InvoiceStatus::Cancelled, InvoiceStatus::Refunded]);
} }
#[Computed]
public function canRefund(): bool
{
return $this->invoice->paid_amount > 0
&& !in_array($this->invoice->status, [InvoiceStatus::Cancelled, InvoiceStatus::Refunded]);
}
public function refundPayment(string $paymentUuid, RefundService $service): void
{
$this->authorize('refunds.initiate');
try {
DB::transaction(function () use ($paymentUuid, $service) {
$service->processRefunds([$paymentUuid], 'استرداد من صفحة الفاتورة', auth()->user());
});
$this->invoice->refresh()->load(['items', 'payments', 'billable', 'creator']);
$this->paymentAmount = max(0, $this->invoice->due_amount) / 100;
session()->flash('success', __('تم استرداد الدفعة بنجاح'));
} catch (DomainException $e) {
session()->flash('error', $e->getMessage());
} catch (\Exception $e) {
session()->flash('error', __('حدث خطأ أثناء الاسترداد'));
}
}
public function render() public function render()
{ {
return view('livewire.invoices.invoice-show', [ return view('livewire.invoices.invoice-show', [
......
...@@ -230,6 +230,20 @@ class="text-xs border border-amber-300 rounded-md px-2 py-1 focus:ring-2 focus:r ...@@ -230,6 +230,20 @@ class="text-xs border border-amber-300 rounded-md px-2 py-1 focus:ring-2 focus:r
<td class="px-4 py-3 text-center"> <td class="px-4 py-3 text-center">
<div class="flex items-center justify-center gap-2"> <div class="flex items-center justify-center gap-2">
<x-ui.print-receipt-button :route="route('receipts.payment.print', $payment->uuid)" size="sm" /> <x-ui.print-receipt-button :route="route('receipts.payment.print', $payment->uuid)" size="sm" />
@if($pStatusValue === 'confirmed' && $payment->direction === 'inbound')
@can('refunds.initiate')
<button type="button"
wire:click="refundPayment('{{ $payment->uuid }}')"
wire:confirm="{{ __('هل أنت متأكد من استرداد هذه الدفعة؟ لا يمكن التراجع عن هذا الإجراء.') }}"
wire:loading.attr="disabled"
wire:target="refundPayment('{{ $payment->uuid }}')"
title="{{ __('استرداد') }}"
class="text-xs px-2 py-1 bg-purple-50 text-purple-600 border border-purple-200 rounded hover:bg-purple-100 transition-colors disabled:opacity-50">
<span wire:loading.remove wire:target="refundPayment('{{ $payment->uuid }}')">{{ __('استرداد') }}</span>
<span wire:loading wire:target="refundPayment('{{ $payment->uuid }}')">...</span>
</button>
@endcan
@endif
@if(auth()->user()?->is_super_admin) @if(auth()->user()?->is_super_admin)
@if($isEditing) @if($isEditing)
<button type="button" wire:click="savePaymentMethod" <button type="button" wire:click="savePaymentMethod"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment