feat(rbi-reserve,savings): Form 1/Form 9 returns UI, branch-wise interest posting reports and summary

- Reports > Interest Posting Reports: per branch and product, generate/regenerate
  at any time, approve; branch column, HO-on-behalf marker, posted txn per account
- Reports > Interest Posting Summary (branch-wise) for the head office, with Excel export
- Day Close warns and disables Close Day while the branch's interest report is unapproved
- Savings product accounting: Interest On Savings (expense), Savings Interest Payable
  and Paid (liability rows, required)
- RBI Form 1 statutory and Form 9 return screens, reserve config updates
- Interest posting report GETs exempted from the response cache

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-01 13:20:01 +05:30
co-authored by Claude Opus 5.5
parent 4f02f24aae
commit b6994c0b76
39 changed files with 4407 additions and 245 deletions
@@ -129,11 +129,30 @@
<!-- ═══ GL accounts ═══ -->
<div class="rrc-card">
<h3 class="rrc-card__title">GL accounts behind each figure</h3>
<div class="rrc-gl-head">
<h3 class="rrc-card__title">GL accounts behind each figure</h3>
<!--
The two returns share a base but maintain their requirement in different assets, so an
administrator setting one up is looking at a different set of heads than one setting up
the other. Showing all of them at once buries the few that matter for the task in hand.
-->
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="rrc-gl-head__filter">
<mat-label>Configuring</mat-label>
<mat-select [(ngModel)]="formFilter" (selectionChange)="onFormFilterChange()">
@for (f of formFilters; track f.value) {
<mat-option [value]="f.value">{{ f.label }}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<p class="rrc-card__hint">
Every role takes as many accounts as it needs — a bank holds current accounts at several other banks, and each
one counts toward what it maintains. Only postable accounts are listed: a header account's balance is the sum of
its children, so mapping both would count those children twice.
@if (formFilter !== 'ALL') {
Heads that build or net the DTL base are shown for either return, since both charge their rate on that same
base.
}
</p>
@if (unmappedCount) {