feat(npa): add branch-wise NPA module with realistic data, pagination and recovery actions
Adds a full NPA (Non-Performing Assets) module mirroring the legacy CBS NPA mega-menu: NPA Reports, NPA Analysis, and NPA Classification screens over a 640-account loan book classified per RBI IRAC norms (Standard through Loss). Same Head-Office/branch-wise access pattern as the Cash/Clearing/ Transfer summary, 20-row pagination on every large table, and a Recovery Action workflow (demand notice, SARFAESI, suit filing, OTS) on the Account Detail screen. Fixes several data-generation bugs so every account stays internally consistent regardless of when it's viewed: disbursement date can no longer predate the account's own overdue history, last-payment date now reflects the most recent recovery entry, the quarter-ago snapshot can't imply more overdue days than the loan's age allowed, and provision held is capped at the account's outstanding balance. Also fixes a text-overflow/dropdown-arrow overlap on long select options (Investment + NPA shared form styles), and marks the GL "Financial Statements" menu items that are already wired to a working dialog.
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
// NPA-specific status colouring layered on top of ../cashier/cashier-shared.scss (pg-*, cctr-*)
|
||||
// and ../investment/investment-shared.scss (inv-kpis, inv-form-*, inv-toast — reused as-is since
|
||||
// they are the same generic "KPI tile / entry form / toast" primitives, not Investment-specific).
|
||||
|
||||
.npa-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 3px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
white-space: nowrap;
|
||||
|
||||
&--standard {
|
||||
background: #f0fdf4;
|
||||
color: #15803d;
|
||||
border: 1px solid #bbf7d0;
|
||||
}
|
||||
|
||||
&--sma0 {
|
||||
background: #fefce8;
|
||||
color: #854d0e;
|
||||
border: 1px solid #fde68a;
|
||||
}
|
||||
|
||||
&--sma1 {
|
||||
background: #fff7ed;
|
||||
color: #9a3412;
|
||||
border: 1px solid #fed7aa;
|
||||
}
|
||||
|
||||
&--sma2 {
|
||||
background: #fff1f0;
|
||||
color: #b91c1c;
|
||||
border: 1px solid #fecdd3;
|
||||
}
|
||||
|
||||
&--substandard {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
|
||||
&--doubtful1 {
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
border: 1px solid #fca5a5;
|
||||
}
|
||||
|
||||
&--doubtful2 {
|
||||
background: #fdf2f8;
|
||||
color: #9d174d;
|
||||
border: 1px solid #fbcfe8;
|
||||
}
|
||||
|
||||
&--doubtful3 {
|
||||
background: #f5f3ff;
|
||||
color: #5b21b6;
|
||||
border: 1px solid #ddd6fe;
|
||||
}
|
||||
|
||||
&--loss {
|
||||
background: #1f2937;
|
||||
color: #f9fafb;
|
||||
border: 1px solid #1f2937;
|
||||
}
|
||||
}
|
||||
|
||||
.npa-kpis--ratio {
|
||||
.inv-kpi__value {
|
||||
&.npa-warn {
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.npa-detail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 12px 20px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.npa-detail-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
|
||||
dt {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #0d1b2a;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
}
|
||||
|
||||
// Wraps tables with more columns than comfortably fit — .pg-card clips overflow with
|
||||
// border-radius, so the scroll container has to live one level in, around the <table> only.
|
||||
.pg-table-scroll {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
// Lets a single field span the whole .inv-form-grid row instead of being squeezed into one
|
||||
// ~220px column — needed for the Account Detail search box, whose "code — name (branch)"
|
||||
// option text is long enough to overflow a narrow column even with ellipsis truncation.
|
||||
.npa-form-field--full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.pg-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
padding: 10px 16px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
background: #f8fafc;
|
||||
font-size: 12.5px;
|
||||
color: #64748b;
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
&__page {
|
||||
font-weight: 600;
|
||||
color: #0d1b2a;
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user