Work on edit payment form. Still has issue preloading contact.
This commit is contained in:
parent
cbc37a4dff
commit
51ef80b0ba
|
|
@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Invoice extends Model
|
class Invoice extends Model
|
||||||
|
|
@ -72,6 +73,11 @@ class Invoice extends Model
|
||||||
return $this->hasMany(InvoiceLine::class);
|
return $this->hasMany(InvoiceLine::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function payments(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(Payment::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function recalculateTotal(): void
|
public function recalculateTotal(): void
|
||||||
{
|
{
|
||||||
$this->attributes['total'] = $this->lines()->sum('amount');
|
$this->attributes['total'] = $this->lines()->sum('amount');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
|
use App\Enums\PaymentMethod;
|
||||||
|
use App\Enums\PaymentStatus;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Payment;
|
||||||
|
use Flux\Flux;
|
||||||
|
use Illuminate\Validation\Rules\Enum;
|
||||||
|
use Livewire\Attributes\Computed;
|
||||||
|
use Livewire\Attributes\On;
|
||||||
|
use Livewire\Attributes\Validate;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
new class extends Component {
|
||||||
|
public ?Payment $payment = null;
|
||||||
|
|
||||||
|
#[Validate('required|integer|exists:invoices,id')]
|
||||||
|
public ?int $invoice_id = null;
|
||||||
|
|
||||||
|
#[Validate('nullable|integer|exists:contacts,id')]
|
||||||
|
public ?int $contact_id = null;
|
||||||
|
|
||||||
|
#[Validate('required|date')]
|
||||||
|
public ?string $payment_date = null;
|
||||||
|
|
||||||
|
#[Validate(['required', new Enum(PaymentStatus::class)])]
|
||||||
|
public ?PaymentStatus $status = PaymentStatus::COMPLETED;
|
||||||
|
|
||||||
|
#[Validate(['required', new Enum(PaymentMethod::class)])]
|
||||||
|
public ?PaymentMethod $payment_method = PaymentMethod::CHECK;
|
||||||
|
|
||||||
|
#[Validate('nullable|string')]
|
||||||
|
public ?string $reference = null;
|
||||||
|
|
||||||
|
#[Validate('required|numeric|min:0.01')]
|
||||||
|
public float $amount = 0;
|
||||||
|
|
||||||
|
#[Validate('nullable|string')]
|
||||||
|
public ?string $notes = null;
|
||||||
|
|
||||||
|
public $contacts = [];
|
||||||
|
|
||||||
|
#[Computed]
|
||||||
|
public function invoices()
|
||||||
|
{
|
||||||
|
return Invoice::where('status', InvoiceStatus::POSTED)->with('client')->get()->sortBy('client.abbreviation');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadContacts(): void
|
||||||
|
{
|
||||||
|
if (!$this->invoice_id) {
|
||||||
|
$this->contacts = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$invoice = Invoice::find($this->invoice_id);
|
||||||
|
$this->contacts = $invoice?->client?->contacts ?? collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedInvoiceId(): void
|
||||||
|
{
|
||||||
|
$this->loadContacts();
|
||||||
|
$this->contact_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[On('edit-payment')]
|
||||||
|
public function loadPayment(int $paymentId): void
|
||||||
|
{
|
||||||
|
$this->payment = Payment::findOrFail($paymentId);
|
||||||
|
|
||||||
|
$this->invoice_id = $this->payment->invoice_id;
|
||||||
|
$this->loadContacts();
|
||||||
|
$this->contact_id = $this->payment->contact_id;
|
||||||
|
$this->payment_date = $this->payment->payment_date->format('Y-m-d');
|
||||||
|
$this->status = $this->payment->status;
|
||||||
|
$this->payment_method = $this->payment->payment_method;
|
||||||
|
$this->reference = $this->payment->reference;
|
||||||
|
$this->amount = $this->payment->amount;
|
||||||
|
$this->notes = $this->payment->notes;
|
||||||
|
|
||||||
|
Flux::modal('edit-payment')->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(): void
|
||||||
|
{
|
||||||
|
$this->validate();
|
||||||
|
|
||||||
|
$this->payment->update([
|
||||||
|
'invoice_id' => $this->invoice_id,
|
||||||
|
'contact_id' => $this->contact_id,
|
||||||
|
'payment_date' => $this->payment_date,
|
||||||
|
'status' => $this->status,
|
||||||
|
'payment_method' => $this->payment_method,
|
||||||
|
'reference' => $this->reference,
|
||||||
|
'amount' => $this->amount,
|
||||||
|
'notes' => $this->notes,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Flux::modal('edit-payment')->close();
|
||||||
|
$this->dispatch('payment-updated');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<flux:modal name="edit-payment" class="md:w-96">
|
||||||
|
<form wire:submit="save" class="space-y-6">
|
||||||
|
<flux:heading size="lg">Edit Payment</flux:heading>
|
||||||
|
|
||||||
|
<flux:input wire:model="payment_date" label="Payment Date" type="date"/>
|
||||||
|
|
||||||
|
<flux:select wire:model.live="invoice_id" label="Invoice" placeholder="Choose an invoice...">
|
||||||
|
<option value="">Select an invoice...</option>
|
||||||
|
@foreach ($this->invoices as $invoice)
|
||||||
|
<option value="{{ $invoice->id }}">{{ $invoice->client->abbreviation }}
|
||||||
|
- {{ $invoice->invoice_number }}</option>
|
||||||
|
@endforeach
|
||||||
|
</flux:select>
|
||||||
|
|
||||||
|
<flux:select wire:model="contact_id" label="Contact" placeholder="Choose a contact...">
|
||||||
|
<option value="">No contact recorded</option>
|
||||||
|
@foreach($contacts as $contact)
|
||||||
|
<flux:select.option :value="$contact->id">{{ $contact->full_name }}</flux:select.option>
|
||||||
|
@endforeach
|
||||||
|
</flux:select>
|
||||||
|
|
||||||
|
<flux:select wire:model="status" label="Status">
|
||||||
|
@foreach(PaymentStatus::cases() as $s)
|
||||||
|
<flux:select.option :value="$s">{{ $s->label() }}</flux:select.option>
|
||||||
|
@endforeach
|
||||||
|
</flux:select>
|
||||||
|
|
||||||
|
<flux:select wire:model="payment_method" label="Payment Method">
|
||||||
|
@foreach(PaymentMethod::cases() as $method)
|
||||||
|
<flux:select.option :value="$method">{{ $method->label() }}</flux:select.option>
|
||||||
|
@endforeach
|
||||||
|
</flux:select>
|
||||||
|
|
||||||
|
<flux:input wire:model="reference" label="Reference"/>
|
||||||
|
|
||||||
|
<flux:input wire:model="amount" label="Amount" type="number" step="0.01"/>
|
||||||
|
|
||||||
|
<flux:textarea wire:model="notes" label="Notes"/>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<flux:button type="submit" variant="primary">Update Payment</flux:button>
|
||||||
|
<flux:button type="button" variant="ghost" wire:click="$dispatch('close-modal', 'edit-payment')">Cancel</flux:button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</flux:modal>
|
||||||
|
</div>
|
||||||
|
|
@ -19,6 +19,11 @@ new class extends Component {
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deletePayment(Payment $payment): void
|
||||||
|
{
|
||||||
|
$payment->delete();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
@ -34,6 +39,7 @@ new class extends Component {
|
||||||
<flux:table.column>Payment Method<br/>Reference</flux:table.column>
|
<flux:table.column>Payment Method<br/>Reference</flux:table.column>
|
||||||
<flux:table.column>Fee Amount</flux:table.column>
|
<flux:table.column>Fee Amount</flux:table.column>
|
||||||
<flux:table.column>Amount Paid</flux:table.column>
|
<flux:table.column>Amount Paid</flux:table.column>
|
||||||
|
<flux:table.column></flux:table.column>
|
||||||
</flux:table.columns>
|
</flux:table.columns>
|
||||||
|
|
||||||
<flux:table.rows>
|
<flux:table.rows>
|
||||||
|
|
@ -46,6 +52,24 @@ new class extends Component {
|
||||||
<flux:table.cell>{{ $payment->payment_method->label() }}<br>{{ $payment->reference }}</flux:table.cell>
|
<flux:table.cell>{{ $payment->payment_method->label() }}<br>{{ $payment->reference }}</flux:table.cell>
|
||||||
<flux:table.cell>{{ formatMoney($payment->fee_amount) }}</flux:table.cell>
|
<flux:table.cell>{{ formatMoney($payment->fee_amount) }}</flux:table.cell>
|
||||||
<flux:table.cell>{{ formatMoney($payment->amount) }}</flux:table.cell>
|
<flux:table.cell>{{ formatMoney($payment->amount) }}</flux:table.cell>
|
||||||
|
<flux:table.cell>
|
||||||
|
<flux:dropdown position="bottom" align="end">
|
||||||
|
<flux:button variant="ghost" size="sm" icon="ellipsis-horizontal" inset="top bottom"></flux:button>
|
||||||
|
|
||||||
|
<flux:navmenu>
|
||||||
|
<flux:menu.item
|
||||||
|
wire:click="$dispatch('edit-payment', { paymentId: {{ $payment->id }} })"
|
||||||
|
icon="pencil">Edit
|
||||||
|
</flux:menu.item>
|
||||||
|
<flux:menu.item
|
||||||
|
wire:click="deletePayment({{ $payment->id }})"
|
||||||
|
wire:confirm="Are you sure you want to delete this payment?"
|
||||||
|
icon="trash"
|
||||||
|
variant="danger">Delete
|
||||||
|
</flux:menu.item>
|
||||||
|
</flux:navmenu>
|
||||||
|
</flux:dropdown>
|
||||||
|
</flux:table.cell>
|
||||||
</flux:table.row>
|
</flux:table.row>
|
||||||
@endforeach
|
@endforeach
|
||||||
</flux:table.rows>
|
</flux:table.rows>
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,6 @@
|
||||||
<livewire:create-payment />
|
<livewire:create-payment />
|
||||||
</div>
|
</div>
|
||||||
<livewire:payment-list />
|
<livewire:payment-list />
|
||||||
|
<livewire:edit-payment />
|
||||||
</div>
|
</div>
|
||||||
</x-layouts::app>
|
</x-layouts::app>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue