Commit b7d24084 authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix(installments): correct last-row rounding in recalculate action

The last pending row was absorbing full rounding relative to
(pendingCount-1), but the plan may have 30 paid rows already.
Now computes the pending interest pool (total - paid interest),
distributes flat per row, and absorbs only the pending rounding
on the final pending row.
Co-Authored-By: 's avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 6beb4544
...@@ -229,17 +229,29 @@ class InstallmentController extends Controller ...@@ -229,17 +229,29 @@ class InstallmentController extends Controller
$runningBalance = bcsub($remaining, (string) ($paidPrincipalSum['s'] ?? '0'), 2); $runningBalance = bcsub($remaining, (string) ($paidPrincipalSum['s'] ?? '0'), 2);
if (bccomp($runningBalance, '0', 2) < 0) $runningBalance = '0.00'; if (bccomp($runningBalance, '0', 2) < 0) $runningBalance = '0.00';
// Compute how much interest is already baked into paid rows
$paidInterestSum = $db->selectOne(
"SELECT COALESCE(SUM(interest), 0) as s FROM installment_schedule
WHERE installment_plan_id = ? AND status = 'paid'",
[(int) $id]
);
$interestAlreadyPaid = (string) ($paidInterestSum['s'] ?? '0');
$pendingInterestPool = bcsub($correctTotalInterest, $interestAlreadyPaid, 2);
if (bccomp($pendingInterestPool, '0', 2) < 0) $pendingInterestPool = '0.00';
$db->beginTransaction(); $db->beginTransaction();
try { try {
$pendingCount = count($pendingRows); $pendingCount = count($pendingRows);
$distributedInterest = '0.00';
foreach ($pendingRows as $idx => $row) { foreach ($pendingRows as $idx => $row) {
$isLast = ($idx === $pendingCount - 1); $isLast = ($idx === $pendingCount - 1);
$principal = $isLast ? $runningBalance : $flatPrincipal; $principal = $isLast ? $runningBalance : $flatPrincipal;
// Last row absorbs rounding in interest too // Last pending row absorbs all remaining interest rounding
$interest = $isLast $interest = $isLast
? bcsub($correctTotalInterest, bcmul($flatInterest, (string) ($pendingCount - 1), 2), 2) ? bcsub($pendingInterestPool, $distributedInterest, 2)
: $flatInterest; : $flatInterest;
if (bccomp($interest, '0', 2) < 0) $interest = '0.00'; if (bccomp($interest, '0', 2) < 0) $interest = '0.00';
$distributedInterest = bcadd($distributedInterest, $interest, 2);
$amount = bcadd($principal, $interest, 2); $amount = bcadd($principal, $interest, 2);
$runningBalance = bcsub($runningBalance, $principal, 2); $runningBalance = bcsub($runningBalance, $principal, 2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment