Files
alrahma_sunday_school_api/app/Services/Invoices/InvoiceManagementService.php
T
2026-06-11 11:46:12 -04:00

148 lines
5.4 KiB
PHP

<?php
namespace App\Services\Invoices;
use App\Models\Enrollment;
use App\Models\Invoice;
use App\Models\Student;
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,
];
}
}