invoiceLedgerService = $invoiceLedgerService ?? new InvoiceLedgerService(); $this->invoiceModel = new InvoiceModel(); } public function invoiceProjection(int $invoiceId): array { $ledger = $this->invoiceLedgerService->calculateInvoice($invoiceId); return [ 'invoice_id' => $invoiceId, 'invoice_gross_charges_cents' => (int) ($ledger['totalAmountCents'] ?? 0), 'applied_discounts_cents' => (int) ($ledger['discountCents'] ?? 0), 'net_charges_cents' => max(0, (int) ($ledger['totalAmountCents'] ?? 0) - (int) ($ledger['discountCents'] ?? 0)), 'valid_payments_cents' => (int) ($ledger['paidCents'] ?? 0), 'completed_cash_refunds_cents' => (int) ($ledger['completedRefundCents'] ?? 0), 'amount_due_cents' => (int) ($ledger['balanceDueCents'] ?? 0), 'customer_credit_cents' => (int) ($ledger['customerCreditCents'] ?? 0), 'approved_refund_reservations_cents' => (int) ($ledger['approvedRefundReservationCents'] ?? 0), 'available_refundable_credit_cents' => (int) ($ledger['availableRefundableCreditCents'] ?? 0), ]; } public function allInvoiceProjections(?string $schoolYear = null): array { $query = $this->invoiceModel->select('id')->orderBy('id', 'ASC'); if ($schoolYear !== null && $schoolYear !== '') { $query->where('school_year', $schoolYear); } $rows = $query->findAll(); return array_map(fn (array $row): array => $this->invoiceProjection((int) $row['id']), $rows); } }