Files
root a30c1398a1
Tests / PHPUnit (push) Failing after 1m21s
fix financials
2026-07-18 22:57:40 -04:00

140 lines
5.6 KiB
PHP

<?php
namespace App\Libraries;
use App\Models\InvoiceModel;
class ParentLedgerService
{
protected InvoiceModel $invoiceModel;
protected InvoiceLedgerService $invoiceLedgerService;
protected RefundEligibilityService $refundEligibilityService;
public function __construct()
{
$this->invoiceModel = new InvoiceModel();
$this->invoiceLedgerService = new InvoiceLedgerService();
$this->refundEligibilityService = new RefundEligibilityService();
}
public function getParentProjection(int $parentId, string $schoolYear, ?string $semester = null): array
{
$invoices = $this->loadInvoices($parentId, $schoolYear, $semester);
$grossChargesCents = 0;
$discountCents = 0;
$netInvoiceChargesCents = 0;
$validPaymentCents = 0;
$completedRefundCents = 0;
$balanceDueCents = 0;
$customerCreditCents = 0;
$approvedRefundReservationCents = 0;
$availableRefundableCreditCents = 0;
$invoiceProjections = [];
foreach ($invoices as $invoice) {
$invoiceId = (int)($invoice['id'] ?? 0);
if ($invoiceId <= 0) {
continue;
}
$ledger = $this->ledgerForInvoice($invoiceId);
$eligibility = $this->eligibilityForSource(
$parentId,
$invoiceId,
'invoice_overpayment',
$invoiceId
);
$invoiceGrossCents = (int)($ledger['totalAmountCents'] ?? 0);
$invoiceDiscountCents = (int)($ledger['discountCents'] ?? 0);
$grossChargesCents += $invoiceGrossCents;
$discountCents += $invoiceDiscountCents;
$netInvoiceChargesCents += max(0, $invoiceGrossCents - $invoiceDiscountCents);
$validPaymentCents += (int)($ledger['paidCents'] ?? 0);
$completedRefundCents += (int)($ledger['completedRefundCents'] ?? 0);
$balanceDueCents += (int)($ledger['balanceDueCents'] ?? 0);
$customerCreditCents += (int)($ledger['customerCreditCents'] ?? 0);
$approvedRefundReservationCents += $eligibility->reservedAmountCents;
$availableRefundableCreditCents += $eligibility->availableAmountCents;
$invoiceProjections[] = [
'invoice_id' => $invoiceId,
'invoice_number' => (string)($invoice['invoice_number'] ?? ''),
'grossChargesCents' => $invoiceGrossCents,
'discountCents' => $invoiceDiscountCents,
'netInvoiceChargesCents' => max(0, $invoiceGrossCents - $invoiceDiscountCents),
'validPaymentCents' => (int)($ledger['paidCents'] ?? 0),
'completedRefundCents' => (int)($ledger['completedRefundCents'] ?? 0),
'balanceDueCents' => (int)($ledger['balanceDueCents'] ?? 0),
'customerCreditCents' => (int)($ledger['customerCreditCents'] ?? 0),
'approvedRefundReservationCents' => $eligibility->reservedAmountCents,
'availableRefundableCreditCents' => $eligibility->availableAmountCents,
'status' => (string)($ledger['status'] ?? ''),
];
}
return [
'parent_id' => $parentId,
'school_year' => $schoolYear,
'semester' => $semester,
'grossChargesCents' => $grossChargesCents,
'discountCents' => $discountCents,
'netInvoiceChargesCents' => $netInvoiceChargesCents,
'validPaymentCents' => $validPaymentCents,
'completedRefundCents' => $completedRefundCents,
'balanceDueCents' => $balanceDueCents,
'customerCreditCents' => $customerCreditCents,
'approvedRefundReservationCents' => $approvedRefundReservationCents,
'availableRefundableCreditCents' => $availableRefundableCreditCents,
'gross_charges' => $this->fromCents($grossChargesCents),
'discounts' => $this->fromCents($discountCents),
'net_invoice_charges' => $this->fromCents($netInvoiceChargesCents),
'valid_payments' => $this->fromCents($validPaymentCents),
'completed_refunds' => $this->fromCents($completedRefundCents),
'balance_due' => $this->fromCents($balanceDueCents),
'customer_credit' => $this->fromCents($customerCreditCents),
'approved_refund_reservations' => $this->fromCents($approvedRefundReservationCents),
'available_refundable_credit' => $this->fromCents($availableRefundableCreditCents),
'invoices' => $invoiceProjections,
];
}
protected function loadInvoices(int $parentId, string $schoolYear, ?string $semester): array
{
$query = $this->invoiceModel
->where('parent_id', $parentId)
->where('school_year', $schoolYear);
if ($semester !== null && $semester !== '') {
$query->where('semester', $semester);
}
return $query->orderBy('id', 'ASC')->findAll();
}
protected function ledgerForInvoice(int $invoiceId): array
{
return $this->invoiceLedgerService->calculateInvoice($invoiceId);
}
protected function eligibilityForSource(
int $parentId,
?int $invoiceId,
string $sourceType,
int $sourceId
): RefundEligibilityResult {
return $this->refundEligibilityService->calculateAvailableCredit(
$parentId,
$invoiceId,
$sourceType,
$sourceId
);
}
private function fromCents(int $cents): string
{
return number_format($cents / 100, 2, '.', '');
}
}