140 lines
5.6 KiB
PHP
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, '.', '');
|
|
}
|
|
}
|