<?php namespace App\Models; use App\Enums\InvoiceStatus; use App\Observers\PaymentObserver; use Illuminate\Database\Eloquent\Attributes\ObservedBy; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\SoftDeletes; #[ObservedBy(PaymentObserver::class)] class Payment extends Model { use SoftDeletes; protected $fillable = [ 'customer_id', 'amount', 'unapplied_amount', 'notes', ]; public function applyToInvoices(): void { $remaining = $this->unapplied_amount ?? $this->amount; $invoices = Invoice::where('customer_id', $this->customer_id) ->where('status', InvoiceStatus::UNPAID) ->orderBy('date') ->get(); foreach ($invoices as $invoice) { $balance = $invoice->remainingBalance(); if ($remaining <= 0) { break; } $applied = min($remaining, $balance); $invoice->payments()->attach($this->id, ['applied_amount' => $applied]); $remaining -= $applied; if ($invoice->remainingBalance() == 0) { $invoice->setStatus(InvoiceStatus::PAID); } elseif ($applied > 0) { $invoice->setStatus(InvoiceStatus::UNPAID); } } $this->unapplied_amount = $remaining; $this->saveQuietly(); } public function customer(): BelongsTo { return $this->belongsTo(Customer::class); } public function invoices(): BelongsToMany { return $this->belongsToMany(Invoice::class) ->withPivot('applied_amount') ->withTimestamps(); } }