Files
cbsnexora/src/app/npa/npa-reports/npa-reports.component.html
T
niteshandClaude Sonnet 5 ebe67cc410 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>
2026-08-02 19:26:19 +05:30

1617 lines
61 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
Copyright since 2025 Mifos Initiative
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<div class="pg">
<header class="pg-head">
<div>
<div class="pg-eyebrow">CREDIT · NON-PERFORMING ASSETS · {{ scopeName | uppercase }}</div>
<h1 class="pg-title">{{ reportLabel(activeReport) }}</h1>
<p class="pg-sub">
RBI IRAC-norm classification (Standard → SMA-0/1/2 → Sub-Standard → Doubtful-1/2/3 → Loss) across
{{ allAccounts.length }} of the bank's {{ bankWideTotalAccounts }} loan accounts, as on {{ asOnDate }}.
</p>
</div>
<div class="pg-toolbar">
@if (isHeadOffice) {
<label class="pg-field">
<span>Branch</span>
<select class="pg-select" [ngModel]="branchFilter" (ngModelChange)="setBranch($event)">
<option value="">-- All Branches --</option>
@for (b of branches; track b.code) {
<option [value]="b.code">{{ b.name }}</option>
}
</select>
</label>
} @else {
<label class="pg-field">
<span>Branch</span>
<span class="pg-chip">{{ scopeName }}</span>
</label>
}
<label class="pg-field">
<span>As On</span>
<input type="text" [(ngModel)]="asOnDate" placeholder="DD-MM-YYYY" />
</label>
<button type="button" class="pg-btn pg-btn--primary" (click)="generate()">Generate</button>
<button type="button" class="pg-btn pg-btn--ghost" [disabled]="generating" (click)="exportExcel()">
{{ generating ? 'Exporting…' : 'Export to Excel' }}
</button>
</div>
</header>
<div class="inv-kpis npa-kpis--ratio">
<div class="inv-kpi">
<span class="inv-kpi__label">Total Advances</span>
<span class="inv-kpi__value">₹{{ totalAdvances | number: '1.0-0' }}</span>
<span class="inv-kpi__sub">{{ allAccounts.length }} accounts</span>
</div>
<div class="inv-kpi">
<span class="inv-kpi__label">Gross NPA (GNPA)</span>
<span class="inv-kpi__value npa-warn">₹{{ gnpaAmount | number: '1.0-0' }}</span>
<span class="inv-kpi__sub"
>{{ npaAccounts.length }} accounts · {{ gnpaRatio | number: '1.2-2' }}% of advances</span
>
</div>
<div class="inv-kpi">
<span class="inv-kpi__label">Net NPA (NNPA)</span>
<span class="inv-kpi__value npa-warn">₹{{ netNpaAmount | number: '1.0-0' }}</span>
<span class="inv-kpi__sub">{{ nnpaRatio | number: '1.2-2' }}% of advances</span>
</div>
<div class="inv-kpi">
<span class="inv-kpi__label">Provision Held (NPA)</span>
<span class="inv-kpi__value">₹{{ totalNpaProvisionHeld | number: '1.0-0' }}</span>
<span class="inv-kpi__sub">Recovered to date ₹{{ totalRecoveredAmount | number: '1.0-0' }}</span>
</div>
<div class="inv-kpi">
<span class="inv-kpi__label">Restructured Accounts</span>
<span class="inv-kpi__value">{{ restructuredAccounts.length }}</span>
<span class="inv-kpi__sub">₹{{ restructuredOutstanding | number: '1.0-0' }} outstanding</span>
</div>
</div>
<div class="cctr-tabs">
@for (g of ['reports', 'analysis', 'classification', 'recovery-mgmt']; track g) {
<button
type="button"
class="pg-btn pg-btn--ghost"
[class.pg-btn--active]="activeGroup === g"
(click)="goToReport(groupOf(g)[0].id)"
>
{{ groupLabels[g] }}
</button>
}
</div>
<div class="cctr-tabs">
@for (m of groupOf(activeGroup); track m.id) {
<button
type="button"
class="pg-btn pg-btn--ghost"
[class.pg-btn--active]="activeReport === m.id"
(click)="goToReport(m.id)"
>
{{ m.label }}
</button>
}
</div>
<!-- ===================== 01 NPA INTEREST ===================== -->
@if (activeReport === 'interest') {
<div class="pg-card">
<div class="pos-section-label">NPA Interest — Income Reversed on Non-Performing Accounts</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th>Stage</th>
<th class="num">Outstanding</th>
<th class="num">Rate</th>
<th class="num">Overdue Days</th>
<th class="num col-out">Interest Reversed</th>
</tr>
</thead>
<tbody>
@for (a of paged(npaAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num">{{ a.interestRate }}%</td>
<td class="num">{{ a.overdueDays }}</td>
<td class="num col-out">₹{{ interestRev(a) | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No NPA accounts in this branch.</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="8">Total Interest Reversed ({{ npaAccounts.length }} accounts)</td>
<td class="num">₹{{ sumInterest(npaAccounts) | number: '1.0-0' }}</td>
</tr>
</tfoot>
</table>
@if (npaAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(npaAccounts) }}–{{ rangeEnd(npaAccounts) }} of {{ npaAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, npaAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(npaAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(npaAccounts)"
(click)="goToPage(currentPage + 1, npaAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 02 NPA STATUS REPORT ===================== -->
@if (activeReport === 'status') {
<div class="pg-card">
<div class="pos-section-label">NPA Status Report — Full Non-Performing Book</div>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th>Secured</th>
<th class="num">Outstanding</th>
<th class="num">Overdue Amount</th>
<th class="num">Overdue Days</th>
<th>NPA Since</th>
<th>Stage</th>
<th>Restructured</th>
<th>Legal Action</th>
<th class="num col-out">Provision Required</th>
</tr>
</thead>
<tbody>
@for (a of paged(npaAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td>{{ a.secured ? 'Yes' : 'No' }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num">₹{{ a.overdueAmount | number: '1.0-0' }}</td>
<td class="num">{{ a.overdueDays }}</td>
<td>{{ npaSince(a) }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td>{{ a.isRestructured ? 'Yes' : 'No' }}</td>
<td [class]="legalActionClass(a.legalActionStatus)">{{ legalActionLabel(a.legalActionStatus) }}</td>
<td class="num col-out">₹{{ provisionReq(a) | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="13" class="pg-empty">No NPA accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (npaAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(npaAccounts) }}–{{ rangeEnd(npaAccounts) }} of {{ npaAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, npaAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(npaAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(npaAccounts)"
(click)="goToPage(currentPage + 1, npaAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 03 NPA RECOVERY REPORT ===================== -->
@if (activeReport === 'recovery') {
<div class="pg-card">
<div class="pos-section-label">Record a Recovery Against an NPA Account</div>
<div class="inv-form-grid">
<label class="inv-form-field">
<span>Account Type</span>
<select [ngModel]="recoveryProductFilter" (ngModelChange)="setRecoveryProductFilter($event)">
<option value="">-- All Account Types --</option>
@for (p of recoveryProductOptions; track p) {
<option [value]="p">{{ p }}</option>
}
</select>
</label>
<label class="inv-form-field">
<span>* NPA Account</span>
<mifosx-search-select
[options]="recoveryAccountSearchOptions"
[(ngModel)]="newRecovery.accountNo"
placeholder="Search account no. or customer name…"
></mifosx-search-select>
</label>
<label class="inv-form-field">
<span>* Recovery Date</span>
<input type="text" [(ngModel)]="newRecovery.date" placeholder="DD-MM-YYYY" />
</label>
<label class="inv-form-field">
<span>* Recovery Amount</span>
<input type="number" [(ngModel)]="newRecovery.amount" />
</label>
<label class="inv-form-field">
<span>Mode</span>
<select [(ngModel)]="newRecovery.mode">
<option>Cash Deposit</option>
<option>Cheque</option>
<option>NEFT/RTGS</option>
<option>Auction / SARFAESI</option>
<option>One-Time Settlement</option>
</select>
</label>
</div>
<div class="inv-form-actions">
<button type="button" class="pg-btn pg-btn--primary" (click)="addRecovery()">Save Recovery Entry</button>
</div>
</div>
<div class="pg-card">
<div
class="pos-section-label"
style="display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap"
>
<span>
NPA Recovery Register — ₹{{ totalRecoveredAmount | number: '1.0-0' }} recovered against ₹{{
gnpaAmount | number: '1.0-0'
}}
GNPA outstanding
</span>
@if (recoveryProductFilter) {
<span class="pg-chip">Filtered: {{ recoveryProductFilter }}</span>
}
</div>
<p class="pg-sub" style="padding: 8px 16px 12px">
Target Recovery is the account's contractual due this month (EMI / interest-servicing / bullet amount) — same
basis as the Recovery Management Dashboard.
</p>
<table class="pg-table">
<thead>
<tr>
<th>Date</th>
<th>Account Type</th>
<th>NPA Category</th>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Mode</th>
<th class="num">Target Recovery</th>
<th class="num col-in">Recovered Amount (Actual)</th>
</tr>
</thead>
<tbody>
@for (r of paged(recoveryRows); track r.accountNo + r.date + r.amount) {
<tr>
<td>{{ r.date }}</td>
<td>{{ r.productName }}</td>
<td>
<span [class]="r.npaCategoryClass">{{ r.npaCategory }}</span>
</td>
<td>
<span class="pg-chip">{{ r.accountNo }}</span>
</td>
<td>{{ r.customerName }}</td>
<td>{{ r.branchName }}</td>
<td>{{ r.mode }}</td>
<td class="num">₹{{ r.targetRecovery | number: '1.0-0' }}</td>
<td class="num col-in">₹{{ r.amount | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No recoveries recorded yet.</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="7">Total (Target once per account · Actual across all entries shown)</td>
<td class="num">₹{{ recoveryTargetTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ recoveryActualTotal | number: '1.0-0' }}</td>
</tr>
</tfoot>
</table>
@if (recoveryRows.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(recoveryRows) }}–{{ rangeEnd(recoveryRows) }} of {{ recoveryRows.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, recoveryRows)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(recoveryRows) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(recoveryRows)"
(click)="goToPage(currentPage + 1, recoveryRows)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 04 NPA SUMMARY REPORT ===================== -->
@if (activeReport === 'summary') {
<div class="pg-card">
<div class="pos-section-label">Stage-wise Summary — {{ scopeName }}</div>
<table class="pg-table">
<thead>
<tr>
<th>Classification</th>
<th class="num">Accounts</th>
<th class="num">Outstanding</th>
<th class="num col-out">Provision Required</th>
</tr>
</thead>
<tbody>
@for (row of stageSummary; track row.stage) {
<tr>
<td>
<span [class]="badgeClass(row.stage)">{{ row.label }}</span>
</td>
<td class="num">{{ row.count }}</td>
<td class="num">₹{{ row.outstanding | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ row.provisionReq | number: '1.0-0' }}</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td>Total</td>
<td class="num">{{ grandTotalAccounts }}</td>
<td class="num">₹{{ grandTotalOutstanding | number: '1.0-0' }}</td>
<td class="num">₹{{ grandTotalProvision | number: '1.0-0' }}</td>
</tr>
</tfoot>
</table>
</div>
@if (isHeadOffice && !branchFilter) {
<div class="pg-card">
<div class="pos-section-label">Branch-wise NPA Summary — All Branches</div>
<table class="pg-table">
<thead>
<tr>
<th>Branch</th>
<th class="num">Total Accounts</th>
<th class="num">Total Advances</th>
<th class="num">NPA Accounts</th>
<th class="num col-out">GNPA Outstanding</th>
<th class="num col-out">Provision Required</th>
<th class="num">GNPA %</th>
</tr>
</thead>
<tbody>
@for (row of branchSummary; track row.branchCode) {
<tr>
<td>
<a href="javascript:void(0)" (click)="setBranch(row.branchCode)">{{ row.branchName }}</a>
</td>
<td class="num">{{ row.totalAccounts }}</td>
<td class="num">₹{{ row.totalAdvances | number: '1.0-0' }}</td>
<td class="num">{{ row.npaCount }}</td>
<td class="num col-out">₹{{ row.npaOutstanding | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ row.provisionReq | number: '1.0-0' }}</td>
<td class="num">{{ row.gnpaRatio | number: '1.2-2' }}%</td>
</tr>
}
</tbody>
</table>
</div>
}
}
<!-- ===================== 05 NPA ACCOUNT DETAIL REPORT ===================== -->
@if (activeReport === 'account-detail') {
<div class="pg-card">
<div class="pos-section-label">Search NPA Account</div>
<div class="inv-form-grid">
<label class="inv-form-field npa-form-field--full">
<span>Account No / Customer</span>
<select [(ngModel)]="selectedAccountNo">
@for (a of npaAccounts; track a.accountNo) {
<option [value]="a.accountNo">{{ a.accountNo }} — {{ a.customerName }} ({{ a.branchName }})</option>
}
</select>
</label>
</div>
<div class="inv-form-actions">
<button type="button" class="pg-btn pg-btn--primary" (click)="searchAccount()">View Details</button>
</div>
</div>
@if (selectedAccount; as a) {
<div class="pg-card">
<div class="pos-section-label npa-detail-header">
<span
>{{ a.accountNo }} — {{ a.customerName }}
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span></span
>
<button type="button" class="pg-btn npa-timeline-trigger" (click)="openTimelineModal()">
<fa-icon icon="history"></fa-icon> Recovery Journey
</button>
</div>
<dl class="npa-detail-grid">
<div class="npa-detail-field">
<dt>Branch</dt>
<dd>{{ a.branchName }}</dd>
</div>
<div class="npa-detail-field">
<dt>Product</dt>
<dd>{{ a.productName }}</dd>
</div>
<div class="npa-detail-field">
<dt>Secured</dt>
<dd>{{ a.secured ? 'Yes' : 'No' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Guarantor</dt>
<dd>{{ a.guarantorName }}</dd>
</div>
<div class="npa-detail-field">
<dt>Sanctioned Amount</dt>
<dd>₹{{ a.sanctionedAmount | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Disbursement Date</dt>
<dd>{{ a.disbursementDate }}</dd>
</div>
<div class="npa-detail-field">
<dt>Interest Rate</dt>
<dd>{{ a.interestRate }}%</dd>
</div>
<div class="npa-detail-field">
<dt>Outstanding Balance</dt>
<dd>₹{{ a.outstandingBalance | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Overdue Amount</dt>
<dd>₹{{ a.overdueAmount | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Overdue Days</dt>
<dd>{{ a.overdueDays }}</dd>
</div>
<div class="npa-detail-field">
<dt>NPA Since</dt>
<dd>{{ npaSince(a) }}</dd>
</div>
<div class="npa-detail-field">
<dt>Restructured</dt>
<dd>{{ a.isRestructured ? 'Yes' : 'No' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Last Payment Date</dt>
<dd>{{ a.lastPaymentDate }}</dd>
</div>
<div class="npa-detail-field">
<dt>Collateral Value</dt>
<dd>₹{{ a.collateralValue | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Provisioning Rate</dt>
<dd>{{ provisionRate(a) }}%</dd>
</div>
<div class="npa-detail-field">
<dt>Provision Required</dt>
<dd>₹{{ provisionReq(a) | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Provision Held</dt>
<dd>₹{{ provisionHeldAmt(a) | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Interest Reversed</dt>
<dd>₹{{ interestRev(a) | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Total Recovered</dt>
<dd>₹{{ recovered(a) | number: '1.0-0' }}</dd>
</div>
<div class="npa-detail-field">
<dt>Movement (vs Last Quarter)</dt>
<dd>{{ movement(a) }}</dd>
</div>
<div class="npa-detail-field">
<dt>NPA Reason</dt>
<dd>{{ a.npaReason }}</dd>
</div>
<div class="npa-detail-field">
<dt>Recovery Officer</dt>
<dd>{{ a.recoveryOfficer }}</dd>
</div>
<div class="npa-detail-field">
<dt>Legal Action Status</dt>
<dd [class]="legalActionClass(a.legalActionStatus)">{{ legalActionLabel(a.legalActionStatus) }}</dd>
</div>
</dl>
</div>
@if (isNpaStageOf(a)) {
<div class="pg-card">
<div class="pos-section-label">Recovery Action — Update Legal Action Status</div>
<div class="inv-form-actions">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="a.legalActionStatus === 'NOTICE_ISSUED'"
(click)="updateLegalAction(a, 'NOTICE_ISSUED')"
>
Issue Demand Notice
</button>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="a.legalActionStatus === 'SARFAESI_INITIATED'"
(click)="updateLegalAction(a, 'SARFAESI_INITIATED')"
>
Initiate SARFAESI Action
</button>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="a.legalActionStatus === 'SUIT_FILED'"
(click)="updateLegalAction(a, 'SUIT_FILED')"
>
File Recovery Suit
</button>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="a.legalActionStatus === 'OTS_NEGOTIATION'"
(click)="updateLegalAction(a, 'OTS_NEGOTIATION')"
>
Mark OTS Negotiation
</button>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="a.legalActionStatus === 'NONE'"
(click)="updateLegalAction(a, 'NONE')"
>
Reset to No Action
</button>
</div>
</div>
}
<div class="pg-card">
<div class="pos-section-label">Recovery History</div>
<table class="pg-table">
<thead>
<tr>
<th>Date</th>
<th>Mode</th>
<th class="num col-in">Amount</th>
</tr>
</thead>
<tbody>
@for (r of a.recoveries; track r.date + r.amount) {
<tr>
<td>{{ r.date }}</td>
<td>{{ r.mode }}</td>
<td class="num col-in">₹{{ r.amount | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="3" class="pg-empty">No recoveries recorded against this account.</td>
</tr>
}
</tbody>
</table>
</div>
}
}
<!-- ===================== 06 NPA MOVEMENT REPORT ===================== -->
@if (activeReport === 'movement') {
<div class="pg-card">
<div class="pos-section-label">Classification Movement — Current Quarter vs Previous Quarter</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Previous Stage</th>
<th>Current Stage</th>
<th>Movement</th>
<th class="num">Outstanding</th>
</tr>
</thead>
<tbody>
@for (a of paged(movedAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>
<span [class]="badgeClass(prevStage(a))">{{ stageLabel(prevStage(a)) }}</span>
</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td>{{ movement(a) }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="7" class="pg-empty">No classification movement in this branch.</td>
</tr>
}
</tbody>
</table>
@if (movedAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(movedAccounts) }}–{{ rangeEnd(movedAccounts) }} of {{ movedAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, movedAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(movedAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(movedAccounts)"
(click)="goToPage(currentPage + 1, movedAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 07 NPA WITH PROVISION AND REQUIRED PROVISION ===================== -->
@if (activeReport === 'provision') {
<div class="pg-card">
<div class="pos-section-label">Provision Held vs Required — Full Loan Book</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Stage</th>
<th class="num">Outstanding</th>
<th class="num">Rate</th>
<th class="num">Provision Required</th>
<th class="num">Provision Held</th>
<th class="num">Shortfall / (Excess)</th>
</tr>
</thead>
<tbody>
@for (a of paged(provisionRows); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num">{{ provisionRate(a) }}%</td>
<td class="num">₹{{ provisionReq(a) | number: '1.0-0' }}</td>
<td class="num">₹{{ provisionHeldAmt(a) | number: '1.0-0' }}</td>
<td class="num" [class.col-out]="shortfall(a) > 0" [class.col-in]="shortfall(a) < 0">
₹{{ shortfall(a) | number: '1.0-0' }}
</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="6">Total ({{ provisionRows.length }} accounts)</td>
<td class="num">₹{{ provisionRequiredTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ provisionHeldTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ provisionShortfallTotal | number: '1.0-0' }}</td>
</tr>
</tfoot>
</table>
@if (provisionRows.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(provisionRows) }}–{{ rangeEnd(provisionRows) }} of {{ provisionRows.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, provisionRows)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(provisionRows) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(provisionRows)"
(click)="goToPage(currentPage + 1, provisionRows)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 08 UNDEBITED INTEREST RECOVERY REPORT ===================== -->
@if (activeReport === 'undebited-interest') {
<div class="pg-card">
<div class="pos-section-label">
Undebited Interest Recovery Report — Memorandum Interest Held Outside the Loan Account (IRAC Norms)
</div>
<p class="pg-sub npa-report-note">
Once an account turns NPA, interest is no longer debited to the borrower's loan account or recognised as income
— it is tracked here as memorandum "undebited interest" and recognised only when actually recovered in cash.
Cash recovered is appropriated to this bucket first; any balance beyond it reduces principal.
</p>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Stage</th>
<th>NPA Since</th>
<th class="num">Days NPA</th>
<th class="num">Rate</th>
<th class="num col-out">Undebited Interest Accrued</th>
<th class="num col-in">Interest Recovered (Cash)</th>
<th class="num">Undebited Interest Balance</th>
</tr>
</thead>
<tbody>
@for (a of paged(npaAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td>{{ npaSince(a) }}</td>
<td class="num">{{ daysSinceNpaOf(a) }}</td>
<td class="num">{{ a.interestRate }}%</td>
<td class="num col-out">₹{{ interestRev(a) | number: '1.0-0' }}</td>
<td class="num col-in">₹{{ interestRecoveredCashOf(a) | number: '1.0-0' }}</td>
<td class="num">₹{{ undebitedInterestBalanceOf(a) | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="10" class="pg-empty">No NPA accounts in this branch.</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="7">Total ({{ npaAccounts.length }} accounts)</td>
<td class="num">₹{{ undebitedInterestAccruedTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ interestRecoveredCashTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ undebitedInterestBalanceTotal | number: '1.0-0' }}</td>
</tr>
</tfoot>
</table>
</div>
@if (npaAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(npaAccounts) }}–{{ rangeEnd(npaAccounts) }} of {{ npaAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, npaAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(npaAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(npaAccounts)"
(click)="goToPage(currentPage + 1, npaAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 09 PROBABLE NPA ===================== -->
@if (activeReport === 'probable') {
<div class="pg-card">
<div class="pos-section-label">
Probable NPA — SMA-2 Accounts Likely to Slip Next Quarter (61–90 Days Overdue)
</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th class="num">Outstanding</th>
<th class="num">Overdue Amount</th>
<th class="num">Overdue Days</th>
<th>Last Payment</th>
<th>Follow-up</th>
</tr>
</thead>
<tbody>
@for (a of paged(probableNpaAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ a.overdueAmount | number: '1.0-0' }}</td>
<td class="num">{{ a.overdueDays }}</td>
<td>{{ a.lastPaymentDate }}</td>
<td>
<span
class="npa-badge"
[class.npa-badge--sma2]="a.overdueDays > 75"
[class.npa-badge--sma0]="a.overdueDays <= 75"
>
{{ a.overdueDays > 75 ? 'Urgent' : 'Monitor' }}
</span>
</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No SMA-2 accounts in this branch.</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="4">Total ({{ probableNpaAccounts.length }} accounts)</td>
<td class="num">₹{{ sumOutstanding(probableNpaAccounts) | number: '1.0-0' }}</td>
<td colspan="4"></td>
</tr>
</tfoot>
</table>
@if (probableNpaAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(probableNpaAccounts) }}–{{ rangeEnd(probableNpaAccounts) }} of
{{ probableNpaAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, probableNpaAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(probableNpaAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(probableNpaAccounts)"
(click)="goToPage(currentPage + 1, probableNpaAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 10 SMA REPORT ===================== -->
@if (activeReport === 'sma') {
<div class="pg-card">
<div class="pos-section-label">Special Mention Accounts — SMA-0 (1–30d) / SMA-1 (31–60d) / SMA-2 (61–90d)</div>
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th>Stage</th>
<th class="num">Outstanding</th>
<th class="num">Overdue Amount</th>
<th class="num">Overdue Days</th>
</tr>
</thead>
<tbody>
@for (a of paged(smaAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ a.overdueAmount | number: '1.0-0' }}</td>
<td class="num">{{ a.overdueDays }}</td>
</tr>
} @empty {
<tr>
<td colspan="8" class="pg-empty">No SMA accounts in this branch.</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="5">Total ({{ smaAccounts.length }} accounts)</td>
<td class="num">₹{{ sumOutstanding(smaAccounts) | number: '1.0-0' }}</td>
<td class="num">₹{{ sumOverdue(smaAccounts) | number: '1.0-0' }}</td>
<td></td>
</tr>
</tfoot>
</table>
@if (smaAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(smaAccounts) }}–{{ rangeEnd(smaAccounts) }} of {{ smaAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, smaAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(smaAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(smaAccounts)"
(click)="goToPage(currentPage + 1, smaAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 11 RECOVERY MANAGEMENT DASHBOARD ===================== -->
@if (activeReport === 'recovery-dashboard') {
<div class="pg-card">
<div class="pos-section-label">Recovery Management Dashboard — Loan-Type Overdue Check</div>
<p class="pg-sub npa-report-note">
Every loan is checked for "is this cycle's dues fully recovered" the way it's actually due — a Term Loan (EMI)
is checked against its instalment, an Overdrawn (CC/OD/KCC) account against its drawing power and interest
servicing, and a Bullet loan (Gold) is checked once past maturity.
</p>
<div class="inv-kpis npa-kpis--three">
@for (row of recoveryTypeSummary; track row.type) {
<div class="inv-kpi">
<span class="inv-kpi__label">{{ row.label }}</span>
<span class="inv-kpi__value">{{ row.accounts }} accounts</span>
<span class="inv-kpi__sub" [class.npa-warn]="row.overdueCount > 0"
>{{ row.overdueCount }} overdue this cycle</span
>
</div>
}
</div>
</div>
<div class="pg-card">
<div class="pos-section-label">Expected vs Actual Recovery — This Cycle, by Loan Type</div>
<table class="pg-table">
<thead>
<tr>
<th>Loan Type</th>
<th class="num">Accounts</th>
<th class="num">Overdue Now</th>
<th class="num">Expected Recovery</th>
<th class="num col-in">Actual Recovery</th>
<th class="num">Variance</th>
</tr>
</thead>
<tbody>
@for (row of recoveryTypeSummary; track row.type) {
<tr>
<td>{{ row.label }}</td>
<td class="num">{{ row.accounts }}</td>
<td class="num">{{ row.overdueCount }}</td>
<td class="num">₹{{ row.expected | number: '1.0-0' }}</td>
<td class="num col-in">₹{{ row.actual | number: '1.0-0' }}</td>
<td class="num" [class.col-out]="row.actual - row.expected < 0">
₹{{ row.actual - row.expected | number: '1.0-0' }}
</td>
</tr>
}
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td>Total</td>
<td class="num">{{ allAccounts.length }}</td>
<td class="num">
{{
recoveryTypeSummary[0].overdueCount +
recoveryTypeSummary[1].overdueCount +
recoveryTypeSummary[2].overdueCount
}}
</td>
<td class="num">₹{{ expectedRecoveryTotal | number: '1.0-0' }}</td>
<td class="num">₹{{ actualRecoveryTotal | number: '1.0-0' }}</td>
<td class="num" [class.col-out]="recoveryVarianceTotal < 0">
₹{{ recoveryVarianceTotal | number: '1.0-0' }}
</td>
</tr>
</tfoot>
</table>
<p class="pg-sub npa-report-note">
Overall recovery rate: {{ recoveryPctTotal | number: '1.1-1' }}% of this cycle's expected dues.
</p>
</div>
<div class="pg-card">
<div class="pos-section-label">Loan-wise Expected vs Actual Recovery</div>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Loan Type</th>
<th class="num">Expected</th>
<th class="num col-in">Actual</th>
<th class="num">Variance</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@for (a of paged(loanWiseRecoveryAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ repaymentTypeLabel(a.repaymentType) }}</td>
<td class="num">₹{{ expectedThisMonth(a) | number: '1.0-0' }}</td>
<td class="num col-in">₹{{ actualThisMonth(a) | number: '1.0-0' }}</td>
<td class="num" [class.col-out]="recoveryVariance(a) < 0">
₹{{ recoveryVariance(a) | number: '1.0-0' }}
</td>
<td>
<span
class="npa-badge"
[class.npa-badge--standard]="recoveryVariance(a) >= 0"
[class.npa-badge--substandard]="recoveryVariance(a) < 0"
>
{{ recoveryVariance(a) >= 0 ? 'Recovered' : 'Shortfall' }}
</span>
</td>
</tr>
} @empty {
<tr>
<td colspan="8" class="pg-empty">No accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (loanWiseRecoveryAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(loanWiseRecoveryAccounts) }}–{{ rangeEnd(loanWiseRecoveryAccounts) }} of
{{ loanWiseRecoveryAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, loanWiseRecoveryAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(loanWiseRecoveryAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(loanWiseRecoveryAccounts)"
(click)="goToPage(currentPage + 1, loanWiseRecoveryAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 12 DAY-WISE OVERDUE REPORT ===================== -->
@if (activeReport === 'daywise-overdue') {
<div class="pg-card">
<div class="pos-section-label">Day-wise Overdue Report — Ageing Buckets</div>
<table class="pg-table">
<thead>
<tr>
<th>Overdue Bucket</th>
<th class="num">Accounts</th>
<th class="num">Outstanding</th>
<th class="num col-out">Overdue Amount</th>
</tr>
</thead>
<tbody>
@for (b of overdueAgeingBuckets; track b.label) {
<tr>
<td>{{ b.label }}</td>
<td class="num">{{ b.count }}</td>
<td class="num">₹{{ b.outstanding | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ b.overdueAmt | number: '1.0-0' }}</td>
</tr>
}
</tbody>
</table>
</div>
<div class="pg-card">
<div class="pos-section-label">Overdue Accounts — Day-wise, Marked by SMA Stage</div>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th>Stage</th>
<th class="num">Overdue Days</th>
<th class="num">Outstanding</th>
<th class="num col-out">Overdue Amount</th>
</tr>
</thead>
<tbody>
@for (a of paged(overdueDaysAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td class="num">{{ a.overdueDays }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ a.overdueAmount | number: '1.0-0' }}</td>
</tr>
} @empty {
<tr>
<td colspan="8" class="pg-empty">No overdue accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (overdueDaysAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(overdueDaysAccounts) }}–{{ rangeEnd(overdueDaysAccounts) }} of
{{ overdueDaysAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, overdueDaysAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(overdueDaysAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(overdueDaysAccounts)"
(click)="goToPage(currentPage + 1, overdueDaysAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 13 DAY-WISE OVERDRAWN REPORT ===================== -->
@if (activeReport === 'daywise-overdrawn') {
<div class="pg-card">
<div class="pos-section-label">
Day-wise Overdrawn Report — Cash Credit / Overdraft / KCC Accounts ({{ overdrawnBreachCount }} of
{{ overdrawnAccounts.length }} breaching Drawing Power)
</div>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th class="num">Drawing Power</th>
<th class="num">Outstanding</th>
<th class="num col-out">Excess Over DP</th>
<th class="num">Days Overdrawn</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@for (a of paged(overdrawnAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td class="num">₹{{ a.drawingPower | number: '1.0-0' }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ excessOverDp(a) | number: '1.0-0' }}</td>
<td class="num">{{ overdrawnBreachOf(a) ? a.overdueDays : 0 }}</td>
<td>
<span
class="npa-badge"
[class.npa-badge--standard]="!overdrawnBreachOf(a)"
[class.npa-badge--substandard]="overdrawnBreachOf(a)"
>
{{ overdrawnBreachOf(a) ? 'DP Breached' : 'Within Limit' }}
</span>
</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No Overdrawn accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (overdrawnAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(overdrawnAccounts) }}–{{ rangeEnd(overdrawnAccounts) }} of
{{ overdrawnAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, overdrawnAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(overdrawnAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(overdrawnAccounts)"
(click)="goToPage(currentPage + 1, overdrawnAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 14 AGRICULTURE / GOLD MARKET VALUE REPORT ===================== -->
@if (activeReport === 'agri-gold-value') {
<div class="pg-card">
<div class="pos-section-label">Agriculture / Gold Market Value Report — Current Security Value vs Loan</div>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th class="num">Outstanding</th>
<th class="num">Collateral Value (At Sanction)</th>
<th class="num">Market Value (Now)</th>
<th class="num">Coverage %</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@for (a of paged(agriGoldAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num">₹{{ a.collateralValue | number: '1.0-0' }}</td>
<td
class="num"
[class.col-in]="a.collateralMarketValue >= a.collateralValue"
[class.col-out]="a.collateralMarketValue < a.collateralValue"
>
₹{{ a.collateralMarketValue | number: '1.0-0' }}
</td>
<td class="num">{{ coverageRatio(a) | number: '1.0-0' }}%</td>
<td>
<span
class="npa-badge"
[class.npa-badge--standard]="!undersecuredOf(a)"
[class.npa-badge--substandard]="undersecuredOf(a)"
>
{{ undersecuredOf(a) ? 'Undersecured' : 'Adequate' }}
</span>
</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No Agriculture / Gold accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (agriGoldAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(agriGoldAccounts) }}–{{ rangeEnd(agriGoldAccounts) }} of
{{ agriGoldAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, agriGoldAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(agriGoldAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(agriGoldAccounts)"
(click)="goToPage(currentPage + 1, agriGoldAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
<!-- ===================== 15 EXCEPTION CHECK REPORT ===================== -->
@if (activeReport === 'exception-check') {
<div class="pg-card">
<div class="pos-section-label">
Exception Check — Security Value vs Loan ({{ exceptionAccounts.length }} accounts undersecured)
</div>
<p class="pg-sub npa-report-note">
Every secured loan's current security market value is expected to stay above its outstanding balance. This lists
the exceptions — where it doesn't — so recovery/credit can review before the next classification review.
</p>
<div class="pg-table-scroll">
<table class="pg-table">
<thead>
<tr>
<th>Account No</th>
<th>Customer</th>
<th>Branch</th>
<th>Product</th>
<th>Stage</th>
<th class="num">Outstanding</th>
<th class="num">Market Value</th>
<th class="num col-out">Shortfall</th>
<th class="num">Coverage %</th>
</tr>
</thead>
<tbody>
@for (a of paged(exceptionAccounts); track a.accountNo) {
<tr>
<td>
<span class="pg-chip">{{ a.accountNo }}</span>
</td>
<td>{{ a.customerName }}</td>
<td>{{ a.branchName }}</td>
<td>{{ a.productName }}</td>
<td>
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
</td>
<td class="num">₹{{ a.outstandingBalance | number: '1.0-0' }}</td>
<td class="num">₹{{ a.collateralMarketValue | number: '1.0-0' }}</td>
<td class="num col-out">₹{{ securityShortfall(a) | number: '1.0-0' }}</td>
<td class="num">{{ coverageRatio(a) | number: '1.0-0' }}%</td>
</tr>
} @empty {
<tr>
<td colspan="9" class="pg-empty">No undersecured accounts in this branch.</td>
</tr>
}
</tbody>
</table>
</div>
@if (exceptionAccounts.length > pageSize) {
<div class="pg-pagination">
<span class="pg-pagination__info"
>Showing {{ rangeStart(exceptionAccounts) }}–{{ rangeEnd(exceptionAccounts) }} of
{{ exceptionAccounts.length }}</span
>
<div class="pg-pagination__controls">
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === 1"
(click)="goToPage(currentPage - 1, exceptionAccounts)"
>
‹ Prev
</button>
<span class="pg-pagination__page">Page {{ currentPage }} of {{ pageCount(exceptionAccounts) }}</span>
<button
type="button"
class="pg-btn pg-btn--ghost"
[disabled]="currentPage === pageCount(exceptionAccounts)"
(click)="goToPage(currentPage + 1, exceptionAccounts)"
>
Next ›
</button>
</div>
</div>
}
</div>
}
</div>
<!-- ===================== Recovery / Collection Journey popup ===================== -->
@if (showTimelineModal && selectedAccount; as a) {
<div class="npa-timeline-backdrop" (click)="closeTimelineModal()">
<div class="npa-timeline-modal" (click)="$event.stopPropagation()">
<header class="npa-timeline-modal__head">
<div class="npa-timeline-modal__title">
<span class="npa-timeline-modal__eyebrow">Recovery / Collection Journey</span>
<h2>{{ a.accountNo }} — {{ a.customerName }}</h2>
<div class="npa-timeline-modal__meta">
<span [class]="badgeClass(stage(a))">{{ stageLabel(stage(a)) }}</span>
<span class="npa-timeline-modal__branch">{{ a.branchName }}</span>
<span class="npa-timeline-modal__count">{{ a.collectionTimeline.length }} touchpoints</span>
</div>
</div>
<button type="button" class="npa-timeline-modal__close" (click)="closeTimelineModal()" aria-label="Close">
<fa-icon icon="times"></fa-icon>
</button>
</header>
<div class="npa-timeline-modal__body">
@if (a.collectionTimeline.length) {
<ol class="npa-timeline">
@for (e of a.collectionTimeline; track e.date + e.type) {
<li [class]="'npa-timeline-item npa-timeline-item--' + timelineEventTone(e.type)">
<span class="npa-timeline-item__icon"><fa-icon [icon]="timelineEventIcon(e.type)"></fa-icon></span>
<div class="npa-timeline-item__body">
<div class="npa-timeline-item__row">
<span class="npa-timeline-item__type">{{ e.type }}</span>
<span class="npa-timeline-item__date">{{ e.date }}</span>
</div>
<p class="npa-timeline-item__remarks">{{ e.remarks }}</p>
<span class="npa-timeline-item__channel">{{ e.channel }}</span>
</div>
</li>
}
</ol>
} @else {
<div class="npa-timeline-empty">
<fa-icon icon="check-circle"></fa-icon>
<p>No collection activity — this account has never gone overdue.</p>
</div>
}
</div>
</div>
</div>
}
<div class="inv-toast" [class.show]="toastVisible">{{ toastMsg }}</div>