72 lines
2.3 KiB
PHP
72 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Admin\Finances;
|
|
|
|
use App\Enums\PaymentStatus;
|
|
use App\Models\TuitionInvoice;
|
|
use App\Models\TuitionPayment;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Http\UploadedFile;
|
|
|
|
class TuitionPaymentService
|
|
{
|
|
public function forInvoice(TuitionInvoice $invoice): Collection
|
|
{
|
|
return $invoice->payments()
|
|
->with('recorder.profile')
|
|
->latest('paid_at')
|
|
->get();
|
|
}
|
|
|
|
public function create(TuitionInvoice $invoice, array $data, ?UploadedFile $file): TuitionPayment
|
|
{
|
|
$payment = $invoice->payments()->create([
|
|
'amount_paid' => $data['amount_paid'],
|
|
'paid_at' => $data['paid_at'],
|
|
'payment_method' => $data['payment_method'] ?? null,
|
|
'status' => $this->resolveStatus($invoice, $data['amount_paid']),
|
|
'recorded_by' => auth()->id(),
|
|
'notes' => $data['notes'] ?? null,
|
|
]);
|
|
|
|
if ($file) {
|
|
$payment->addMedia($file)->toMediaCollection('payment_proof');
|
|
}
|
|
|
|
return $payment;
|
|
}
|
|
|
|
public function update(TuitionPayment $payment, array $data, ?UploadedFile $file): TuitionPayment
|
|
{
|
|
$payment->amount_paid = $data['amount_paid'];
|
|
$payment->paid_at = $data['paid_at'];
|
|
$payment->payment_method = $data['payment_method'] ?? null;
|
|
$payment->status = $this->resolveStatus($payment->invoice, $data['amount_paid'], excludePaymentId: $payment->id);
|
|
$payment->notes = $data['notes'] ?? null;
|
|
$payment->update();
|
|
|
|
if ($file) {
|
|
$payment->addMedia($file)->toMediaCollection('payment_proof');
|
|
}
|
|
|
|
return $payment;
|
|
}
|
|
|
|
public function delete(TuitionPayment $payment): bool
|
|
{
|
|
return $payment->delete();
|
|
}
|
|
|
|
private function resolveStatus(TuitionInvoice $invoice, float|string $amountPaid, ?int $excludePaymentId = null): PaymentStatus
|
|
{
|
|
$otherPaidTotal = $invoice->payments()
|
|
->when($excludePaymentId, fn ($query) => $query->where('id', '!=', $excludePaymentId))
|
|
->sum('amount_paid');
|
|
|
|
$totalPaid = round($otherPaidTotal + (float) $amountPaid, 2);
|
|
$amountDue = round((float) $invoice->amount_due, 2);
|
|
|
|
return $totalPaid >= $amountDue ? PaymentStatus::Paid : PaymentStatus::Partial;
|
|
}
|
|
}
|