Skip to content

feat(loans): Pending EMI column + one-off July 2026 accrual fix - #36

Merged
parameshjava merged 2 commits into
mainfrom
feat/loans-pending-emi-column
Aug 6, 2026
Merged

feat(loans): Pending EMI column + one-off July 2026 accrual fix#36
parameshjava merged 2 commits into
mainfrom
feat/loans-pending-emi-column

Conversation

@parameshjava

Copy link
Copy Markdown
Owner

Follow-up to #35.

1. Pending EMI column

New column between EMI and Start date showing the number of installments still unpaid — a plain count, not a rupee value. Accrual-model loans render .

  • src/lib/constants.tsUNPAID_EMI_STATUSES = ['scheduled', 'partially_paid', 'overdue'], matching the filter loan_emi_balances uses for pending_interest / next_due_date.
  • Both list pages (/dashboard/loans, /admin/loans) tally loan_emi_schedule rows in those statuses per loan. loan_emi_balances exposes overdue/past-due counts but not the remaining-term count, so this counts schedule rows directly rather than needing a view migration. Added as a third leg of the existing Promise.all — no extra latency.
  • Sortable, right-aligned, and included in the CSV/PDF export.

2. scripts/prod/fix-emi-cutover-duplicate-accruals.sql (one-off, not a migration)

Loans converted to the EMI model are charged July 2026 interest twice:

  • loan_interest_accruals — the EOM cron wrote a period_end = 2026-07-31 row while the loan was still on the accrual model.
  • loan_emi_schedule — installment Split deployment pipeline per action #1 is due 2026-08-10, and under the migration 041 model an installment due on the 10th carries the previous month's interest, i.e. July.

The script has preview → delete → verify statements, scoped to repayment_model = 'emi' and that single period_end. Accruals with any settlement are skipped (loan_interest_payments.accrual_id is ON DELETE RESTRICT, so a part-paid row would abort the statement). A waive-instead-of-delete variant is included, commented out, for keeping the month visible in the audit timeline.

Going forward the cron is already correct — fn_compute_loan_interest_for skips repayment_model = 'emi' (migration 039, patch E). This only cleans up rows written before each loan was converted. The remaining gap: convertToEmi doesn't waive an existing accrual for the cutover month, so a loan converted after a month-end run will recreate the overlap. Not fixed here.

Verification

  • npm run build
  • tsc --noEmit
  • npm run lint ✅ (only the pre-existing _prev warning in pending-interest-panel.tsx)
  • npm test ✅ 244 passed / 23 files

The SQL script has not been run against any database.

🤖 Generated with Claude Code

parameshjava and others added 2 commits August 6, 2026 20:24
Shows how many installments are still unpaid (scheduled + partially paid +
overdue) per EMI loan; accrual-model loans render a dash.

loan_emi_balances exposes overdue/past-due counts but not the remaining-term
count, so both list pages tally loan_emi_schedule rows directly — added as a
third leg of the existing Promise.all, so no extra latency.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Loans converted to EMI were charged July interest twice: the EOM cron wrote a
period_end 2026-07-31 accrual while the loan was still on the accrual model,
and installment #1 (due 2026-08-10) already carries July's interest under the
041 due-on-the-10th model.

Preview / delete / verify statements, scoped to repayment_model = 'emi' and
that single period_end, skipping any accrual with a settlement (the junction
FK is ON DELETE RESTRICT). Includes a waive-instead-of-delete variant.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aits-fcf-tracker Ready Ready Preview Aug 6, 2026 2:56pm

@parameshjava
parameshjava merged commit d80864f into main Aug 6, 2026
3 checks passed
@parameshjava
parameshjava deleted the feat/loans-pending-emi-column branch August 6, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant