81 lines
3.1 KiB
PHP
81 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Admin\Finances;
|
|
|
|
use App\Models\TuitionInvoice;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class TuitionInvoiceService
|
|
{
|
|
/**
|
|
* @param array<int> $studentIds
|
|
* @return Collection<int, array<int>> daftar academic_term_id per student_id yang sudah punya tagihan
|
|
*/
|
|
public function getInvoicedTermIdsByStudent(array $studentIds): Collection
|
|
{
|
|
return TuitionInvoice::query()
|
|
->whereIn('student_id', $studentIds)
|
|
->get(['student_id', 'academic_term_id'])
|
|
->groupBy('student_id')
|
|
->map(fn ($rows) => $rows->pluck('academic_term_id')->values()->all());
|
|
}
|
|
|
|
public function paginated(
|
|
int $perPage = 25,
|
|
string $search = '',
|
|
?int $academicTermId = null,
|
|
?string $status = null,
|
|
?string $paymentMethod = null,
|
|
): LengthAwarePaginator {
|
|
return TuitionInvoice::query()
|
|
->select(['id', 'student_id', 'academic_term_id', 'amount_due', 'due_date'])
|
|
->withSum('payments as paid_total', 'amount_paid')
|
|
->withCount('payments')
|
|
->with(['student.user.profile', 'student.department', 'academicTerm:id,name,semester,start_date,end_date'])
|
|
->when($search, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('student_number', 'like', "%{$search}%")
|
|
->orWhereHas('user.profile', fn ($q) => $q->where('full_name', 'like', "%{$search}%"))))
|
|
->when($academicTermId, fn ($q) => $q->where('academic_term_id', $academicTermId))
|
|
->when($status, fn ($q) => match ($status) {
|
|
'paid' => $q->havingRaw('COALESCE(paid_total, 0) >= amount_due'),
|
|
'partial' => $q->havingRaw('COALESCE(paid_total, 0) > 0 AND COALESCE(paid_total, 0) < amount_due'),
|
|
'unpaid' => $q->havingRaw('COALESCE(paid_total, 0) <= 0'),
|
|
default => $q,
|
|
})
|
|
->when($paymentMethod, fn ($q) => $q->whereHas('payments', fn ($q) => $q->where('payment_method', $paymentMethod)))
|
|
->latest()
|
|
->paginate($perPage);
|
|
}
|
|
|
|
public function createMany(array $studentIds, array $data): void
|
|
{
|
|
DB::transaction(function () use ($studentIds, $data) {
|
|
foreach ($studentIds as $studentId) {
|
|
TuitionInvoice::create([
|
|
'student_id' => $studentId,
|
|
'academic_term_id' => $data['academic_term_id'],
|
|
'amount_due' => $data['amount_due'],
|
|
'due_date' => $data['due_date'],
|
|
]);
|
|
}
|
|
});
|
|
}
|
|
|
|
public function update(TuitionInvoice $invoice, array $data): TuitionInvoice
|
|
{
|
|
$invoice->student_id = $data['student_id'];
|
|
$invoice->academic_term_id = $data['academic_term_id'];
|
|
$invoice->amount_due = $data['amount_due'];
|
|
$invoice->due_date = $data['due_date'] ?? null;
|
|
$invoice->update();
|
|
|
|
return $invoice;
|
|
}
|
|
|
|
public function delete(TuitionInvoice $invoice): bool
|
|
{
|
|
return $invoice->delete();
|
|
}
|
|
}
|