- 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>
217 lines
8.2 KiB
HTML
217 lines
8.2 KiB
HTML
<!--
|
|
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">TREASURY · INVESTMENT</div>
|
|
<h1 class="pg-title">Investment Portfolio Dashboard</h1>
|
|
<p class="pg-sub">
|
|
Consolidated position across FD, Govt Security, Non-SLR, Bonds, Mutual Fund and Share holdings as on
|
|
{{ asOnDate }}.
|
|
</p>
|
|
</div>
|
|
<div class="pg-toolbar">
|
|
<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">
|
|
<div class="inv-kpi">
|
|
<span class="inv-kpi__label">Total Holdings</span>
|
|
<span class="inv-kpi__value">{{ totalHoldings }}</span>
|
|
<span class="inv-kpi__sub">{{ activeCount }} active · {{ maturedCount }} matured</span>
|
|
</div>
|
|
<div class="inv-kpi">
|
|
<span class="inv-kpi__label">Total Invested (Face Value)</span>
|
|
<span class="inv-kpi__value">₹{{ totalFaceValue | number: '1.2-2' }}</span>
|
|
</div>
|
|
<div class="inv-kpi">
|
|
<span class="inv-kpi__label">Accrued Interest / Income</span>
|
|
<span class="inv-kpi__value col-in">₹{{ totalAccruedInterest | number: '1.2-2' }}</span>
|
|
</div>
|
|
<div class="inv-kpi">
|
|
<span class="inv-kpi__label">Projected Value at Maturity</span>
|
|
<span class="inv-kpi__value">₹{{ totalMaturityValue | number: '1.2-2' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="pg-card">
|
|
<div class="pos-section-label">Instrument-wise Break-up</div>
|
|
<table class="pg-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Instrument Type</th>
|
|
<th class="num">Holdings</th>
|
|
<th class="num">Face Value</th>
|
|
<th class="num col-in">Accrued Interest</th>
|
|
<th class="num col-net">Maturity Value</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (s of summaries; track s.type) {
|
|
<tr>
|
|
<td>{{ s.label }}</td>
|
|
<td class="num">{{ s.count }}</td>
|
|
<td class="num">₹{{ s.faceValue | number: '1.2-2' }}</td>
|
|
<td class="num col-in">₹{{ s.accruedInterest | number: '1.2-2' }}</td>
|
|
<td class="num col-net">₹{{ s.maturityValue | number: '1.2-2' }}</td>
|
|
<td>
|
|
<a class="pg-btn pg-btn--ghost" [routerLink]="s.route">Open</a>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="cctr-total-row">
|
|
<td>Total</td>
|
|
<td class="num">{{ totalHoldings }}</td>
|
|
<td class="num">₹{{ totalFaceValue | number: '1.2-2' }}</td>
|
|
<td class="num">₹{{ totalAccruedInterest | number: '1.2-2' }}</td>
|
|
<td class="num">₹{{ totalMaturityValue | number: '1.2-2' }}</td>
|
|
<td></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="pg-card">
|
|
<div class="pos-section-label">Portfolio Allocation — Target vs Actual</div>
|
|
<p class="pg-sub">
|
|
Govt Security, Non-SLR, Mutual Fund and Share targets trace to RBI's SLR floor (18% of NDTL) and Non-SLR ceiling
|
|
(≤10% of deposits) for Urban Co-operative Banks; Fixed Deposit and Bond are board-approved policy choices within
|
|
the room that framework leaves.
|
|
</p>
|
|
<table class="pg-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Instrument Type</th>
|
|
<th>Target Basis</th>
|
|
<th class="num">Target %</th>
|
|
<th class="num">Actual %</th>
|
|
<th class="num">Actual Value</th>
|
|
<th class="num">Variance</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for (a of allocationVsTarget; track a.type) {
|
|
<tr>
|
|
<td>{{ a.label }}</td>
|
|
<td>
|
|
<span class="inv-badge" [class.inv-badge--matured]="a.isRbiLinked">
|
|
{{ a.isRbiLinked ? 'RBI SLR / Non-SLR Norm' : 'Board Policy' }}
|
|
</span>
|
|
</td>
|
|
<td class="num">{{ a.targetPct }}%</td>
|
|
<td class="num">{{ a.actualPct }}%</td>
|
|
<td class="num">₹{{ a.actualValue | number: '1.2-2' }}</td>
|
|
<td
|
|
class="num"
|
|
[class.col-out]="a.statusLabel !== 'Within Target'"
|
|
[class.col-in]="a.statusLabel === 'Within Target'"
|
|
>
|
|
{{ a.variancePct > 0 ? '+' : '' }}{{ a.variancePct }}%
|
|
</td>
|
|
<td>
|
|
<span
|
|
class="inv-badge"
|
|
[class.inv-badge--active]="a.statusLabel === 'Within Target'"
|
|
[class.inv-badge--sold]="a.statusLabel === 'Over-Allocated'"
|
|
[class.inv-badge--written_off]="a.statusLabel === 'Under-Allocated'"
|
|
>
|
|
{{ a.statusLabel }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="cctr-total-row">
|
|
<td>Total</td>
|
|
<td class="num">100%</td>
|
|
<td class="num">100%</td>
|
|
<td class="num">₹{{ totalFaceValue | number: '1.2-2' }}</td>
|
|
<td colspan="2"></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="pg-card">
|
|
<div class="pos-section-label">Due-Date Diary — Maturing Within 90 Days</div>
|
|
@if (maturingSoon.length === 0) {
|
|
<div class="pg-empty">No holdings maturing in the next 90 days.</div>
|
|
} @else {
|
|
<div>
|
|
@for (h of maturingSoon; track h.certNo) {
|
|
<div class="inv-maturity-row">
|
|
<span>
|
|
<span class="pg-chip">{{ h.certNo }}</span>
|
|
{{ h.scriptName }} — {{ h.party }} ({{ instrumentLabel(h.instrumentType) }})
|
|
</span>
|
|
<span>
|
|
Matures {{ h.maturityDate }} ·
|
|
<span
|
|
class="inv-maturity-days"
|
|
[class.inv-maturity-days--soon]="daysLeft(h) <= 30"
|
|
[class.inv-maturity-days--ok]="daysLeft(h) > 30"
|
|
>
|
|
{{ daysLeft(h) }} days
|
|
</span>
|
|
</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<div class="pg-card">
|
|
<div class="pos-section-label">Quick Entry</div>
|
|
<div class="inv-nav-grid" style="padding: 16px">
|
|
<a class="inv-nav-card" routerLink="/investment/fd">
|
|
<span class="inv-nav-card__label">Fixed Deposit</span>
|
|
<span class="inv-nav-card__count">{{ summaries[0].count }}</span>
|
|
<span class="inv-nav-card__value">Purchase / Interest / Sell / Write-off</span>
|
|
</a>
|
|
<a class="inv-nav-card" routerLink="/investment/bonds">
|
|
<span class="inv-nav-card__label">Govt Security / Non-SLR / Bonds / MF</span>
|
|
<span class="inv-nav-card__count">{{
|
|
summaries[1].count + summaries[2].count + summaries[3].count + summaries[4].count
|
|
}}</span>
|
|
<span class="inv-nav-card__value">Purchase / Interest / Sell / Amortize</span>
|
|
</a>
|
|
<a class="inv-nav-card" routerLink="/investment/share">
|
|
<span class="inv-nav-card__label">Share Entry</span>
|
|
<span class="inv-nav-card__count">{{ summaries[5].count }}</span>
|
|
<span class="inv-nav-card__value">Purchase / Dividend / Sell / Write-off</span>
|
|
</a>
|
|
<a class="inv-nav-card" routerLink="/investment/interest">
|
|
<span class="inv-nav-card__label">Interest</span>
|
|
<span class="inv-nav-card__count">5</span>
|
|
<span class="inv-nav-card__value">FD / Bond Calculation & Registers</span>
|
|
</a>
|
|
<a class="inv-nav-card" routerLink="/investment/masters">
|
|
<span class="inv-nav-card__label">Masters</span>
|
|
<span class="inv-nav-card__count">10</span>
|
|
<span class="inv-nav-card__value">Script / Broker / Party / Control Params</span>
|
|
</a>
|
|
<a class="inv-nav-card" routerLink="/investment/reports">
|
|
<span class="inv-nav-card__label">Reports</span>
|
|
<span class="inv-nav-card__count">20+</span>
|
|
<span class="inv-nav-card__value">Balance / Ledger / Maturity / Portfolio</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="inv-toast" [class.show]="toastVisible">{{ toastMsg }}</div>
|