feat(investment,npa): RBI-grounded targets, GL-tracked interest posting, date/search pickers

- Correct Investment portfolio allocation and Loan Origination product-mix targets against
  RBI's UCB SLR/Non-SLR framework and PSL circulars, with a Target Basis column distinguishing
  RBI-mandated vs board-policy rows (Excel export included).
- Expand Investment holdings dataset with more near-term maturities so the Due-Date Diary
  reflects a realistic spread across FD/Govt Security/Non-SLR/Bond.
- Add From/To period-based Interest Calculation & Post (with GL selection for both posting and
  receiving) across the Investment Interest module, FD Entry and Bond Entry screens; fix a bug
  where a posted period kept re-appearing as due since accrual wasn't tracked per-holding.
- Add a reusable DD-MM-YYYY date-picker component and roll it out across all Investment date
  fields.
- NPA Summary Report: drop SMA-0/1/2 from the stage-wise table (kept in Day-wise Overdue only).
- NPA Recovery Report: add Account Type / NPA Category / Target-vs-Actual columns, a shared
  Account Type filter driving both the account picker and the register, and a searchable
  (fixed-position, not clipped by card overflow) account select for long lists.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 19:26:19 +05:30
co-authored by Claude Sonnet 5
parent d7f5bfe5f5
commit ebe67cc410
20 changed files with 1401 additions and 226 deletions
@@ -71,6 +71,9 @@ interface MixTargetRow {
actualPct: number;
variancePct: number;
status: TargetStatus;
/** True only for the two rows whose target is an actual RBI PSL sub-target (Agriculture 18% /
* Micro Enterprises 7.5% of ANBC) rather than an internal business-plan assumption. */
isRbiMandated: boolean;
}
type ViewId = 'pipeline' | 'new' | 'channel' | 'bc' | 'share' | 'target';
@@ -389,7 +392,8 @@ export class LoanPipelineComponent implements OnInit {
targetPct,
actualPct,
variancePct: actualPct - targetPct,
status: targetStatus(actualPct, targetPct, 3)
status: targetStatus(actualPct, targetPct, 3),
isRbiMandated: p.code === 'KCC' || p.code === 'CC'
};
});
}
@@ -413,7 +417,8 @@ export class LoanPipelineComponent implements OnInit {
targetPct,
actualPct,
variancePct: actualPct - targetPct,
status: targetStatus(actualPct, targetPct, 3)
status: targetStatus(actualPct, targetPct, 3),
isRbiMandated: false
};
});
}
@@ -626,6 +631,7 @@ export class LoanPipelineComponent implements OnInit {
subtitle,
headers: [
'Mix',
'Target Basis',
'Target %',
'Actual %',
'Variance (pp)',
@@ -633,6 +639,7 @@ export class LoanPipelineComponent implements OnInit {
],
widths: [
26,
18,
12,
12,
14,
@@ -641,6 +648,7 @@ export class LoanPipelineComponent implements OnInit {
rows: [
...this.productTargetRows.map((r) => [
`Product — ${r.label}`,
r.isRbiMandated ? 'RBI PSL Sub-Target' : 'Internal Target',
r.targetPct,
Number(r.actualPct.toFixed(1)),
Number(r.variancePct.toFixed(1)),
@@ -648,6 +656,7 @@ export class LoanPipelineComponent implements OnInit {
]),
...this.channelTargetRows.map((r) => [
`Channel — ${r.label}`,
'Internal Target',
r.targetPct,
Number(r.actualPct.toFixed(1)),
Number(r.variancePct.toFixed(1)),