73 lines
1.8 KiB
PHP
73 lines
1.8 KiB
PHP
<?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;
|
|
use Illuminate\Support\Collection;
|
|
|
|
#[ObservedBy(PaymentObserver::class)]
|
|
|
|
class Payment extends Model
|
|
{
|
|
use SoftDeletes;
|
|
|
|
protected $fillable = [
|
|
'customer_id',
|
|
'check_number',
|
|
'date',
|
|
'amount',
|
|
'unapplied_amount',
|
|
'notes',
|
|
];
|
|
|
|
public function applyToInvoices(Collection $invoices): void
|
|
{
|
|
$remaining = $this->unapplied_amount ?? $this->amount;
|
|
|
|
$filteredInvoices = $invoices->whereIn('status', [
|
|
InvoiceStatus::UNPAID,
|
|
InvoiceStatus::PARTIALLY_PAID,
|
|
]);
|
|
|
|
foreach ($filteredInvoices 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::PARTIALLY_PAID);
|
|
}
|
|
}
|
|
|
|
$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();
|
|
}
|
|
}
|