@@ -22,6 +22,7 @@ use App\Models\StudentClassModel;
|
||||
use App\Models\StudentSectionDistributionDraftModel;
|
||||
use App\Controllers\View\EmailController;
|
||||
use App\Controllers\View\InvoiceController;
|
||||
use App\Libraries\RefundEligibilityService;
|
||||
use App\Models\StaffAttendanceModel;
|
||||
use App\Libraries\StaffTimeOffLinkService;
|
||||
use App\Models\AttendanceDayModel;
|
||||
@@ -2855,19 +2856,51 @@ class AdministratorController extends BaseController
|
||||
$existingRefund = $this->refundModel->where('invoice_id', $invoice['id'])->first();
|
||||
|
||||
if ($existingRefund) {
|
||||
$this->refundModel->update($existingRefund['id'], [
|
||||
'refund_amount' => $refundAmount,
|
||||
'status' => 'Pending',
|
||||
$refundId = (int)$existingRefund['id'];
|
||||
$status = strtolower((string)($existingRefund['status'] ?? ''));
|
||||
$isApprovedState = in_array($status, ['approved', 'partial', 'paid', 'partially_paid'], true);
|
||||
$calculatedCents = max(0, (int)round($refundAmount * 100));
|
||||
$paidCents = (new RefundEligibilityService())->getCompletedPayoutTotalCentsForRefund($refundId);
|
||||
$targetCents = $isApprovedState ? max($calculatedCents, $paidCents) : $calculatedCents;
|
||||
$update = [
|
||||
'refund_amount' => $targetCents / 100,
|
||||
'updated_by' => session()->get('user_id') ?? null,
|
||||
]);
|
||||
];
|
||||
if ($isApprovedState) {
|
||||
$update['approved_amount_cents'] = $targetCents;
|
||||
} else {
|
||||
$update['status'] = 'Pending';
|
||||
$update['requested_amount_cents'] = $targetCents;
|
||||
}
|
||||
if ($isApprovedState && $paidCents > $calculatedCents) {
|
||||
$message = sprintf(
|
||||
'Completed payouts (%0.2f) exceed recalculated refundable credit (%0.2f).',
|
||||
$paidCents / 100,
|
||||
$calculatedCents / 100
|
||||
);
|
||||
$update['reconciliation_status'] = 'requires_review';
|
||||
$update['reconciliation_reason'] = $message;
|
||||
$update['reconciliation_required_at'] = utc_now();
|
||||
log_message('critical', 'Refund reconciliation required for refund #' . $refundId . ': ' . $message);
|
||||
} else {
|
||||
$update['reconciliation_status'] = null;
|
||||
$update['reconciliation_reason'] = null;
|
||||
$update['reconciliation_required_at'] = null;
|
||||
}
|
||||
$this->refundModel->update($refundId, $update);
|
||||
} else {
|
||||
$this->refundModel->insert([
|
||||
'parent_id' => $pid,
|
||||
'school_year' => $invoice['school_year'],
|
||||
'invoice_id' => $invoice['id'],
|
||||
'refund_amount' => $refundAmount,
|
||||
'requested_amount_cents' => (int)round($refundAmount * 100),
|
||||
'approved_amount_cents' => null,
|
||||
'currency' => 'USD',
|
||||
'refund_paid_amount' => 0.0,
|
||||
'status' => 'Pending',
|
||||
'source_type' => 'invoice_overpayment',
|
||||
'source_id' => (int)$invoice['id'],
|
||||
'requested_at' => utc_now(),
|
||||
'updated_by' => session()->get('user_id') ?? null,
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user