67 lines
2.6 KiB
PHP
67 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Libraries;
|
|
|
|
use App\Models\InvoiceModel;
|
|
|
|
class FinancialCorrectionReportService
|
|
{
|
|
private InvoiceModel $invoiceModel;
|
|
private FinancialReportProjectionService $projectionService;
|
|
|
|
public function __construct(?FinancialReportProjectionService $projectionService = null)
|
|
{
|
|
$this->invoiceModel = new InvoiceModel();
|
|
$this->projectionService = $projectionService ?? new FinancialReportProjectionService();
|
|
}
|
|
|
|
public function invoiceReport(?string $schoolYear = null): array
|
|
{
|
|
$query = $this->invoiceModel->orderBy('id', 'ASC');
|
|
if ($schoolYear !== null && $schoolYear !== '') {
|
|
$query->where('school_year', $schoolYear);
|
|
}
|
|
|
|
$rows = [];
|
|
foreach ($query->findAll() as $invoice) {
|
|
$projection = $this->projectionService->invoiceProjection((int) $invoice['id']);
|
|
$storedTotalCents = $this->toCents((float) ($invoice['total_amount'] ?? 0));
|
|
$storedBalanceCents = $this->toCents((float) ($invoice['balance'] ?? 0));
|
|
$flags = [];
|
|
|
|
if ($storedTotalCents !== $projection['invoice_gross_charges_cents']) {
|
|
$flags[] = 'stored_total_mismatch';
|
|
}
|
|
if ($storedBalanceCents !== $projection['amount_due_cents']) {
|
|
$flags[] = 'stored_balance_mismatch';
|
|
}
|
|
if ($projection['completed_cash_refunds_cents'] < 0) {
|
|
$flags[] = 'wrong_refund_sign';
|
|
}
|
|
if ($projection['applied_discounts_cents'] > $projection['invoice_gross_charges_cents']) {
|
|
$flags[] = 'discount_above_eligible_base';
|
|
}
|
|
|
|
$rows[] = [
|
|
'invoice_id' => (int) $invoice['id'],
|
|
'invoice_number' => $invoice['invoice_number'] ?? null,
|
|
'stored_total_cents' => $storedTotalCents,
|
|
'canonical_frozen_charge_total_cents' => $projection['invoice_gross_charges_cents'],
|
|
'valid_payment_total_cents' => $projection['valid_payments_cents'],
|
|
'completed_refund_payout_total_cents' => $projection['completed_cash_refunds_cents'],
|
|
'applied_discount_total_cents' => $projection['applied_discounts_cents'],
|
|
'expected_balance_due_cents' => $projection['amount_due_cents'],
|
|
'expected_customer_credit_cents' => $projection['customer_credit_cents'],
|
|
'flags' => $flags,
|
|
];
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
private function toCents(float $amount): int
|
|
{
|
|
return (int) round($amount * 100);
|
|
}
|
|
}
|