151 lines
5.5 KiB
PHP
151 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Invoices;
|
|
|
|
use App\Models\Enrollment;
|
|
use App\Models\Invoice;
|
|
use App\Models\Student;
|
|
use App\Models\StudentClass;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class InvoiceManagementService
|
|
{
|
|
public function __construct(private InvoiceConfigService $config)
|
|
{
|
|
}
|
|
|
|
public function getManagementData(?string $schoolYear): array
|
|
{
|
|
$schoolYear = trim((string) ($schoolYear ?? ''));
|
|
if ($schoolYear === '') {
|
|
$schoolYear = $this->config->getSchoolYear();
|
|
}
|
|
|
|
$schoolYears = DB::table('invoices')
|
|
->select('school_year')
|
|
->distinct()
|
|
->orderBy('school_year', 'DESC')
|
|
->pluck('school_year')
|
|
->map(fn ($val) => (string) $val)
|
|
->filter(fn ($val) => $val !== '')
|
|
->values()
|
|
->all();
|
|
|
|
if (empty($schoolYears)) {
|
|
$schoolYears = [$schoolYear];
|
|
}
|
|
|
|
$invoiceData = [];
|
|
$parents = User::getUsersByRoleAndSchoolYear('parent', $schoolYear);
|
|
|
|
foreach ($parents as $parent) {
|
|
$students = Student::query()
|
|
->where('parent_id', $parent['id'])
|
|
->get()
|
|
->map(fn ($r) => $r->toArray())
|
|
->all();
|
|
|
|
$parentData = [
|
|
'parent_name' => trim(($parent['firstname'] ?? '') . ' ' . ($parent['lastname'] ?? '')),
|
|
'parent_id' => (int) $parent['id'],
|
|
'enrolledKids' => [],
|
|
'withdrawnKids' => [],
|
|
'invoice_amount' => 0,
|
|
'refund_amount' => 0,
|
|
'last_updated' => null,
|
|
'invoice_date' => null,
|
|
'invoice_id' => null,
|
|
];
|
|
|
|
$invoices = Invoice::getInvoicesByParentId((int) $parent['id'], $schoolYear);
|
|
foreach ($invoices as $invoice) {
|
|
if (!$invoice) {
|
|
continue;
|
|
}
|
|
|
|
$parentData['invoice_amount'] = (float) ($invoice['total_amount'] ?? 0);
|
|
$parentData['last_updated'] = $invoice['updated_at'] ?? null;
|
|
$parentData['invoice_id'] = $invoice['id'] ?? null;
|
|
|
|
if (!empty($invoice['issue_date'])) {
|
|
$tzName = $this->config->getTimezone();
|
|
$parentData['invoice_date'] = (new \DateTimeImmutable($invoice['issue_date'], new \DateTimeZone('UTC')))
|
|
->setTimezone(new \DateTimeZone($tzName))
|
|
->format('Y-m-d H:i:s');
|
|
} else {
|
|
$parentData['invoice_date'] = !empty($invoice['updated_at'])
|
|
? date('Y-m-d H:i:s', strtotime($invoice['updated_at']))
|
|
: null;
|
|
}
|
|
|
|
$refund = DB::table('refunds')
|
|
->selectRaw('COALESCE(SUM(refund_paid_amount),0) AS refund_paid_amount')
|
|
->where('parent_id', $parent['id'])
|
|
->where('school_year', $schoolYear)
|
|
->whereIn('status', ['Partial', 'Paid'])
|
|
->first();
|
|
|
|
$parentData['refund_amount'] = (float) ($refund->refund_paid_amount ?? 0.0);
|
|
break;
|
|
}
|
|
|
|
foreach ($students as $student) {
|
|
$grade = 'N/A';
|
|
$studentClass = DB::table('student_class')
|
|
->where('student_id', $student['id'])
|
|
->where('school_year', $schoolYear)
|
|
->first();
|
|
|
|
if ($studentClass && isset($studentClass->class_section_id)) {
|
|
$classSection = DB::table('classSection')
|
|
->where('class_section_id', $studentClass->class_section_id)
|
|
->first();
|
|
if ($classSection && isset($classSection->class_section_name)) {
|
|
$grade = $classSection->class_section_name;
|
|
}
|
|
}
|
|
|
|
$enrollments = Enrollment::query()
|
|
->where('student_id', $student['id'])
|
|
->where('school_year', $schoolYear)
|
|
->get()
|
|
->map(fn ($r) => $r->toArray())
|
|
->all();
|
|
|
|
foreach ($enrollments as $enrollment) {
|
|
$kid = [
|
|
'name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
|
|
'grade' => $grade,
|
|
'tuition_fee' => (float) ($enrollment['tuition_fee'] ?? 0),
|
|
];
|
|
|
|
switch ($enrollment['enrollment_status']) {
|
|
case 'payment pending':
|
|
case 'enrolled':
|
|
$parentData['enrolledKids'][] = $kid;
|
|
break;
|
|
case 'withdraw under review':
|
|
case 'withdrawn':
|
|
case 'refund pending':
|
|
$parentData['withdrawnKids'][] = $kid;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($parentData['enrolledKids']) || !empty($parentData['withdrawnKids'])) {
|
|
$invoiceData[] = $parentData;
|
|
}
|
|
}
|
|
|
|
return [
|
|
'schoolYear' => $schoolYear,
|
|
'schoolYears' => $schoolYears,
|
|
'invoices' => $invoiceData,
|
|
];
|
|
}
|
|
}
|