700 lines
28 KiB
HTML
700 lines
28 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="fiu-root">
|
||
<!-- HEADER -->
|
||
<div class="fiu-head">
|
||
<div class="fiu-head-left">
|
||
<fa-icon icon="shield-alt" class="fiu-head-ic"></fa-icon>
|
||
<div>
|
||
<h2 class="fiu-head-t">Financial Intelligence Unit – India (FIU-IND)</h2>
|
||
<div class="fiu-head-s">
|
||
{{ bank.name }} · {{ bank.branch }} · Reporting Month <strong>{{ bank.reportingMonth }}</strong>
|
||
· PMLA 2002 / FINnet 2.0
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-head-meta">
|
||
<div>
|
||
<span class="fiu-meta-l">Principal Officer</span><span class="fiu-meta-v">{{ bank.principalOfficer }}</span>
|
||
</div>
|
||
<div>
|
||
<span class="fiu-meta-l">REBANK BUID</span><span class="fiu-meta-v mono">{{ bank.reBuid }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TABS -->
|
||
<div class="fiu-tabs">
|
||
<button class="fiu-tab" [class.active]="activeTab === 'dashboard'" (click)="showTab('dashboard')">
|
||
<fa-icon icon="chart-pie"></fa-icon> Dashboard
|
||
</button>
|
||
<button class="fiu-tab" [class.active]="activeTab === 'ctr'" (click)="showTab('ctr')">
|
||
<fa-icon icon="coins"></fa-icon> CTR — Cash Transactions
|
||
</button>
|
||
<button class="fiu-tab" [class.active]="activeTab === 'str'" (click)="showTab('str')">
|
||
<fa-icon icon="exclamation-triangle"></fa-icon> STR — Suspicious
|
||
</button>
|
||
<button class="fiu-tab" [class.active]="activeTab === 'customers'" (click)="showTab('customers')">
|
||
<fa-icon icon="users"></fa-icon> Customer Cards
|
||
</button>
|
||
<button class="fiu-tab" [class.active]="activeTab === 'files'" (click)="showTab('files')">
|
||
<fa-icon icon="file-csv"></fa-icon> FINnet Files
|
||
</button>
|
||
</div>
|
||
|
||
<!-- DASHBOARD -->
|
||
@if (activeTab === 'dashboard') {
|
||
<div class="fiu-section">
|
||
<div class="fiu-kpis">
|
||
<div class="fiu-kpi fiu-kpi--blue">
|
||
<div class="fiu-kpi-ic"><fa-icon icon="file-alt"></fa-icon></div>
|
||
<div>
|
||
<div class="fiu-kpi-n">{{ totalReports | number }}</div>
|
||
<div class="fiu-kpi-l">CTR Reports</div>
|
||
<div class="fiu-kpi-sub">{{ totalCtrTxns | number }} txns this cycle</div>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-kpi fiu-kpi--teal">
|
||
<div class="fiu-kpi-ic"><fa-icon icon="coins"></fa-icon></div>
|
||
<div>
|
||
<div class="fiu-kpi-n">₹{{ totalCtrAmount | number: '1.0-0' }}</div>
|
||
<div class="fiu-kpi-l">Total CTR Amount</div>
|
||
<div class="fiu-kpi-sub">aggregate cash movement</div>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-kpi fiu-kpi--amber">
|
||
<div class="fiu-kpi-ic"><fa-icon icon="exclamation-triangle"></fa-icon></div>
|
||
<div>
|
||
<div class="fiu-kpi-n">{{ pendingStr | number }}</div>
|
||
<div class="fiu-kpi-l">STR Pending</div>
|
||
<div class="fiu-kpi-sub">draft / PO review</div>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-kpi fiu-kpi--green">
|
||
<div class="fiu-kpi-ic"><fa-icon icon="check-circle"></fa-icon></div>
|
||
<div>
|
||
<div class="fiu-kpi-n">{{ filedStr | number }}</div>
|
||
<div class="fiu-kpi-l">STR Filed</div>
|
||
<div class="fiu-kpi-sub">acknowledged by FIU</div>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-kpi fiu-kpi--purple">
|
||
<div class="fiu-kpi-ic"><fa-icon icon="users"></fa-icon></div>
|
||
<div>
|
||
<div class="fiu-kpi-n">{{ totalCustomers | number }}</div>
|
||
<div class="fiu-kpi-l">Customers in Cycle</div>
|
||
<div class="fiu-kpi-sub">{{ kc1.length }} ind · {{ kc2.length }} entity</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Compliance cards -->
|
||
<div class="fiu-compliance">
|
||
<div class="dc-card">
|
||
<div class="dc-card-h">
|
||
<fa-icon icon="check-circle" class="dc-ok"></fa-icon><span>CTR — Cash Transaction Report</span>
|
||
</div>
|
||
<div class="dc-meta">
|
||
Threshold: <strong>₹{{ bank.cashThreshold | number }}</strong> per single txn / aggregate per month
|
||
</div>
|
||
<div class="dc-meta">Due: <strong>15 Feb 2026</strong></div>
|
||
<button class="dc-btn" (click)="showTab('ctr')"><fa-icon icon="external-link-alt"></fa-icon> Open</button>
|
||
</div>
|
||
<div class="dc-card">
|
||
<div class="dc-card-h">
|
||
<fa-icon icon="exclamation-triangle" class="dc-warn"></fa-icon><span>STR — Suspicious Transaction</span>
|
||
</div>
|
||
<div class="dc-meta">Filing window: <strong>within 7 days of detection</strong></div>
|
||
<div class="dc-meta">
|
||
Pending: <strong>{{ pendingStr }}</strong> · Filed: <strong>{{ filedStr }}</strong>
|
||
</div>
|
||
<button class="dc-btn" (click)="showTab('str')"><fa-icon icon="external-link-alt"></fa-icon> Open</button>
|
||
</div>
|
||
<div class="dc-card">
|
||
<div class="dc-card-h"><fa-icon icon="file-csv" class="dc-info"></fa-icon><span>FINnet 2.0 Files</span></div>
|
||
<div class="dc-meta">6 CSVs: TC1 / TC2 / KC1 / KC2 / Account_Detail / Account_Person_Relation</div>
|
||
<div class="dc-meta">+ STR XML for suspicious filings</div>
|
||
<button class="dc-btn" (click)="showTab('files')"><fa-icon icon="external-link-alt"></fa-icon> Open</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- CTR -->
|
||
@if (activeTab === 'ctr') {
|
||
<div class="fiu-section">
|
||
<!-- LIVE: cash-related AML alerts awaiting AML Officer review -->
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>Live Cash Alerts</h3>
|
||
<p>
|
||
Raised by the transaction-monitoring rule engine — review and whitelist or escalate to Principal Officer
|
||
</p>
|
||
</div>
|
||
<select class="fiu-inp" [(ngModel)]="amlAlertStatusFilter" (ngModelChange)="loadAmlAlerts()">
|
||
<option value="">All statuses</option>
|
||
<option value="RAISED">Raised</option>
|
||
<option value="UNDER_REVIEW">Under Review</option>
|
||
<option value="WHITELISTED">Whitelisted</option>
|
||
<option value="ESCALATED">Escalated</option>
|
||
</select>
|
||
</div>
|
||
<div class="fiu-tbl-wrap">
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Client</th>
|
||
<th>Type</th>
|
||
<th>Rule</th>
|
||
<th class="ta-r">Amount</th>
|
||
<th>Raised On</th>
|
||
<th>Status</th>
|
||
<th>Notes</th>
|
||
<th>Action</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (alert of amlAlerts; track alert.id) {
|
||
<tr>
|
||
<td>{{ alert.id }}</td>
|
||
<td>{{ alert.clientDisplayName }}</td>
|
||
<td>{{ alert.transactionType }}</td>
|
||
<td>{{ alert.ruleCode }} — {{ alert.ruleDescription }}</td>
|
||
<td class="ta-r mono">₹{{ alert.amount | number: '1.0-0' }}</td>
|
||
<td>{{ alert.raisedOn | date: 'medium' }}</td>
|
||
<td>
|
||
<span [class]="amlStatusClass(alert.status)">{{ alert.status }}</span>
|
||
</td>
|
||
<td>
|
||
@if (alert.status === 'RAISED' || alert.status === 'UNDER_REVIEW') {
|
||
<input
|
||
type="text"
|
||
class="fiu-inp"
|
||
placeholder="Review notes"
|
||
[(ngModel)]="amlReviewNotes[alert.id]"
|
||
/>
|
||
} @else {
|
||
<span class="muted">{{ alert.reviewNotes }}</span>
|
||
}
|
||
</td>
|
||
<td>
|
||
@if (alert.status === 'RAISED' || alert.status === 'UNDER_REVIEW') {
|
||
<div class="fiu-action-group" *mifosxHasPermission="'REVIEW_AML_ALERT'">
|
||
<button class="fiu-btn fiu-btn-g" (click)="whitelistAlert(alert)">Whitelist</button>
|
||
<button class="fiu-btn fiu-btn-xml" (click)="escalateAlert(alert)">Escalate</button>
|
||
</div>
|
||
}
|
||
</td>
|
||
</tr>
|
||
} @empty {
|
||
<tr>
|
||
<td colspan="9" class="fiu-empty">No live alerts.</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- LIVE: monthly CTR reports (mechanical, threshold-based) -->
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>Monthly CTR Reports</h3>
|
||
<p>
|
||
Threshold: <strong>₹{{ bank.cashThreshold | number }}</strong> per single txn / connected aggregate
|
||
per month
|
||
</p>
|
||
</div>
|
||
<div class="fiu-action-group">
|
||
<input class="fiu-inp" type="month" [(ngModel)]="ctrGenerateMonth" />
|
||
<button class="fiu-btn fiu-btn-g" *mifosxHasPermission="'REVIEW_AML_ALERT'" (click)="generateCtrReport()">
|
||
Generate
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-tbl-wrap">
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th>Month</th>
|
||
<th>Generated On</th>
|
||
<th class="ta-c">Records</th>
|
||
<th>Status</th>
|
||
<th>Submitted On</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (r of amlCtrReports; track r.id) {
|
||
<tr>
|
||
<td>{{ r.reportMonth }}</td>
|
||
<td>{{ r.generatedOn | date: 'medium' }}</td>
|
||
<td class="ta-c">{{ r.recordCount }}</td>
|
||
<td>
|
||
<span [class]="amlStatusClass(r.status)">{{ r.status }}</span>
|
||
</td>
|
||
<td>{{ r.submittedOn ? (r.submittedOn | date: 'medium') : '—' }}</td>
|
||
</tr>
|
||
} @empty {
|
||
<tr>
|
||
<td colspan="5" class="fiu-empty">No CTR reports generated yet.</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- FINnet export template (separate concern — TC1/TC2 file-format generation) -->
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>FINnet TC2 Export Template</h3>
|
||
<p>
|
||
All cash transactions ≥ ₹{{ bank.cashThreshold | number }} (single or aggregate per month per account)
|
||
</p>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportTc2()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download TC2.csv
|
||
</button>
|
||
</div>
|
||
|
||
<div class="fiu-filters">
|
||
<div class="fiu-filter">
|
||
<label>Type</label>
|
||
<select class="fiu-inp" [(ngModel)]="ctrFilterMode">
|
||
<option value="">All</option>
|
||
<option value="Deposit">Deposit</option>
|
||
<option value="Withdrawal">Withdrawal</option>
|
||
</select>
|
||
</div>
|
||
<div class="fiu-filter">
|
||
<label>Account contains</label>
|
||
<input class="fiu-inp" type="text" [(ngModel)]="ctrFilterAccount" placeholder="A/c partial" />
|
||
</div>
|
||
<div class="fiu-filter">
|
||
<label>Min Amount (₹)</label>
|
||
<input class="fiu-inp" type="number" [(ngModel)]="ctrFilterMinAmount" placeholder="0" />
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-g" (click)="resetCtrFilters()">Reset</button>
|
||
</div>
|
||
|
||
<div class="fiu-tbl-wrap">
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th class="ta-c">Ref</th>
|
||
<th>Account</th>
|
||
<th>Customer</th>
|
||
<th class="ta-c">Type</th>
|
||
<th>Date / Time</th>
|
||
<th class="ta-r">Amount</th>
|
||
<th>Instrument</th>
|
||
<th>Branch</th>
|
||
<th class="ta-c">Relationship</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (t of filteredCtr; track t.txnId) {
|
||
<tr>
|
||
<td class="ta-c">{{ t.reportRefNo }}</td>
|
||
<td class="mono">{{ t.accountNumber }}</td>
|
||
<td>{{ t.customerName }}</td>
|
||
<td class="ta-c">
|
||
<span
|
||
class="dir-pill"
|
||
[class.deposit]="t.depositOrWithdrawal === 'Deposit'"
|
||
[class.withdrawal]="t.depositOrWithdrawal === 'Withdrawal'"
|
||
>
|
||
{{ t.depositOrWithdrawal }}
|
||
</span>
|
||
</td>
|
||
<td>
|
||
{{ t.txnDate }} <span class="muted">{{ t.txnTime }}</span>
|
||
</td>
|
||
<td class="ta-r mono">
|
||
<strong>₹{{ t.txnAmount | number: '1.0-0' }}</strong>
|
||
</td>
|
||
<td>
|
||
{{ t.instrumentType }} <span class="muted">{{ t.instrumentId }}</span>
|
||
</td>
|
||
<td class="mono">{{ t.branchCode }}</td>
|
||
<td class="ta-c">
|
||
<span class="rel-pill" [class.non-cust]="t.relationshipFlag === 'Non-Customer'">{{
|
||
t.relationshipFlag
|
||
}}</span>
|
||
</td>
|
||
</tr>
|
||
} @empty {
|
||
<tr>
|
||
<td colspan="9" class="fiu-empty">No transactions match the filters.</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- STR -->
|
||
@if (activeTab === 'str') {
|
||
<div class="fiu-section">
|
||
<!-- LIVE: STR cases with full Principal Officer actions -->
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>Live STR Cases</h3>
|
||
<p>
|
||
Escalated by an AML Officer; Principal Officer investigates, concludes and files with FIU-IND within 7
|
||
working days
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="fiu-tbl-wrap">
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Client</th>
|
||
<th class="ta-c">Cumulative Cases</th>
|
||
<th>Assigned PO</th>
|
||
<th>Conclusion</th>
|
||
<th>FIU Due Date</th>
|
||
<th>Status</th>
|
||
<th>Action</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (sc of amlStrCases; track sc.id) {
|
||
<tr [class.selected-row]="selectedStrCase?.id === sc.id">
|
||
<td>{{ sc.id }}</td>
|
||
<td>{{ sc.clientDisplayName }}</td>
|
||
<td class="ta-c" [class.escalation-warning]="sc.cumulativeStrCaseCountForClient >= 3">
|
||
{{ sc.cumulativeStrCaseCountForClient }}
|
||
</td>
|
||
<td>{{ sc.assignedPoUsername || '—' }}</td>
|
||
<td>{{ sc.conclusion || '—' }}</td>
|
||
<td>{{ sc.fiuDueDate || '—' }}</td>
|
||
<td>
|
||
<span [class]="amlStatusClass(sc.status)">{{ sc.status }}</span>
|
||
</td>
|
||
<td><button class="fiu-btn fiu-btn-g" (click)="selectStrCase(sc)">Investigate</button></td>
|
||
</tr>
|
||
} @empty {
|
||
<tr>
|
||
<td colspan="8" class="fiu-empty">No STR cases yet.</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
@if (selectedStrCase) {
|
||
<div class="str-case-detail">
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>STR Case #{{ selectedStrCase.id }} — {{ selectedStrCase.clientDisplayName }}</h3>
|
||
<p>
|
||
Alert #{{ selectedStrCase.alertId }} ·
|
||
{{ selectedStrCase.cumulativeStrCaseCountForClient }} cumulative STR case(s) for this client
|
||
@if (selectedStrCase.cumulativeStrCaseCountForClient >= 3) {
|
||
<span class="escalation-badge">Risk category auto-escalated</span>
|
||
}
|
||
</p>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-g" (click)="closeStrCaseDetail()">Close</button>
|
||
</div>
|
||
|
||
<div class="case-form" *mifosxHasPermission="'CONCLUDE_AML_STR'">
|
||
<div class="form-row">
|
||
<label for="fiuInvestigationNotes">Investigation notes (source-of-transaction history reviewed)</label>
|
||
<textarea id="fiuInvestigationNotes" rows="3" [(ngModel)]="concludeInvestigationNotes"></textarea>
|
||
</div>
|
||
<div class="form-row">
|
||
<label for="fiuSourceOfFundsNotes">Source-of-funds notes</label>
|
||
<textarea id="fiuSourceOfFundsNotes" rows="2" [(ngModel)]="concludeSourceOfFundsNotes"></textarea>
|
||
</div>
|
||
<div class="form-row conclusion-row">
|
||
<label>
|
||
<input type="radio" name="fiuConclusion" value="NOT_SUSPICIOUS" [(ngModel)]="concludeConclusion" />
|
||
Not suspicious (whitelist)
|
||
</label>
|
||
<label>
|
||
<input type="radio" name="fiuConclusion" value="SUSPICIOUS" [(ngModel)]="concludeConclusion" />
|
||
Suspicious (file STR)
|
||
</label>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-xml" (click)="concludeStrCase()">Conclude</button>
|
||
|
||
@if (selectedStrCase.status === 'CONCLUDED_SUSPICIOUS') {
|
||
<div class="file-str-row">
|
||
<label for="fiuFileReferenceNo">FIU-IND acknowledgement / reference number</label>
|
||
<input id="fiuFileReferenceNo" class="fiu-inp" type="text" [(ngModel)]="fileReferenceNo" />
|
||
<button class="fiu-btn fiu-btn-xml" (click)="fileStrCase()">Mark STR Filed</button>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- FINnet export template (separate concern — STR XML file-format generation) -->
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>FINnet STR XML Export Template</h3>
|
||
<p>Detected by AML rules engine + branch compliance officers; filed within 7 days</p>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-xml" (click)="exportStrXml()">
|
||
<fa-icon icon="file-alt"></fa-icon> Download STR XML
|
||
</button>
|
||
</div>
|
||
|
||
<div class="fiu-filters">
|
||
<div class="fiu-filter">
|
||
<label>Status</label>
|
||
<select class="fiu-inp" [(ngModel)]="strFilterStatus">
|
||
<option value="">All</option>
|
||
<option value="draft">Draft</option>
|
||
<option value="po-review">PO Review</option>
|
||
<option value="filed">Filed</option>
|
||
<option value="rejected">Rejected</option>
|
||
</select>
|
||
</div>
|
||
<div class="fiu-filter">
|
||
<label>Risk Category</label>
|
||
<select class="fiu-inp" [(ngModel)]="strFilterRisk">
|
||
<option value="">All</option>
|
||
<option value="structuring">Structuring</option>
|
||
<option value="dormant-revival">Dormant Revival</option>
|
||
<option value="high-risk-country">High-Risk Country</option>
|
||
<option value="unusual-pattern">Unusual Pattern</option>
|
||
<option value="pep-related">PEP Related</option>
|
||
<option value="sanctions-hit">Sanctions Hit</option>
|
||
</select>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-g" (click)="resetStrFilters()">Reset</button>
|
||
</div>
|
||
|
||
<div class="fiu-str-list">
|
||
@for (s of filteredStr; track s.reportRefNo) {
|
||
<div class="str-card" [class.str-card--filed]="s.status === 'filed'">
|
||
<div class="str-card-h">
|
||
<div class="str-card-id">
|
||
<span class="str-ref">STR-{{ s.reportRefNo }}</span>
|
||
<span class="status-pill" [class]="'st-' + s.status">{{ statusLabel(s.status) }}</span>
|
||
<span class="risk-pill" [class]="'rk-' + s.riskCategory">{{ riskLabel(s.riskCategory) }}</span>
|
||
</div>
|
||
<div class="str-card-amt">
|
||
<span class="muted">{{ s.depositOrWithdrawal }}</span>
|
||
<strong>₹{{ s.txnAmount | number: '1.0-0' }}</strong>
|
||
</div>
|
||
</div>
|
||
<div class="str-card-body">
|
||
<div class="str-meta">
|
||
<div>
|
||
<label>Customer</label><span>{{ s.customerName }}</span>
|
||
</div>
|
||
<div>
|
||
<label>Account</label><span class="mono">{{ s.accountNumber }}</span>
|
||
</div>
|
||
<div>
|
||
<label>Txn Date</label><span>{{ s.txnDate }} {{ s.txnTime }}</span>
|
||
</div>
|
||
<div>
|
||
<label>Detected</label><span>{{ s.detectedOn }}</span>
|
||
</div>
|
||
<div>
|
||
<label>Flagged By</label><span>{{ s.flaggedBy }}</span>
|
||
</div>
|
||
<div>
|
||
<label>Instrument</label><span>{{ s.instrumentType }} {{ s.instrumentId }}</span>
|
||
</div>
|
||
</div>
|
||
<div class="str-narrative">
|
||
<label>Narrative</label>
|
||
<p>{{ s.narrative }}</p>
|
||
</div>
|
||
@if (s.poRemarks) {
|
||
<div class="str-po-remarks">
|
||
<label><fa-icon icon="check-circle"></fa-icon> PO Remarks</label>
|
||
<p>{{ s.poRemarks }}</p>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
} @empty {
|
||
<div class="fiu-empty-card">No STR records match the filters.</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- CUSTOMER CARDS -->
|
||
@if (activeTab === 'customers') {
|
||
<div class="fiu-section">
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>Customer Cards — KC1 (Individuals) & KC2 (Entities)</h3>
|
||
<p>Customers attached to reports filed in this cycle</p>
|
||
</div>
|
||
<div class="fiu-action-group">
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportKc1()"><fa-icon icon="file-csv"></fa-icon> KC1.csv</button>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportKc2()"><fa-icon icon="file-csv"></fa-icon> KC2.csv</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="fiu-tbl-wrap">
|
||
<div class="fiu-tbl-h">KC1 — Individuals</div>
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th class="ta-c">Ref</th>
|
||
<th>UCIC</th>
|
||
<th>Name</th>
|
||
<th class="ta-c">Gender</th>
|
||
<th>DOB</th>
|
||
<th>PAN</th>
|
||
<th>Mobile</th>
|
||
<th>City</th>
|
||
<th class="ta-r">Annual Income</th>
|
||
<th class="ta-c">Risk</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (k of kc1; track k.ucic) {
|
||
<tr>
|
||
<td class="ta-c">{{ k.reportRefNo }}</td>
|
||
<td class="mono">{{ k.ucic }}</td>
|
||
<td>{{ k.firstName }} {{ k.middleName }} {{ k.lastName }}</td>
|
||
<td class="ta-c">{{ k.gender }}</td>
|
||
<td>{{ k.dob }}</td>
|
||
<td class="mono">{{ k.pan }}</td>
|
||
<td class="mono">{{ k.mobileNumber }}</td>
|
||
<td>{{ k.city }}, {{ k.state }}</td>
|
||
<td class="ta-r mono">₹{{ k.annualIncome | number }}</td>
|
||
<td class="ta-c">
|
||
<span class="risk-tag" [class]="'rk-tag-' + k.riskLevel.toLowerCase()">{{ k.riskLevel }}</span>
|
||
</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="fiu-tbl-wrap">
|
||
<div class="fiu-tbl-h">KC2 — Entities</div>
|
||
<table class="fiu-tbl">
|
||
<thead>
|
||
<tr>
|
||
<th class="ta-c">Ref</th>
|
||
<th>UCIC</th>
|
||
<th>Entity Name</th>
|
||
<th>PAN</th>
|
||
<th>GSTIN</th>
|
||
<th>City</th>
|
||
<th>Type</th>
|
||
<th>Owner (if Sole Prop)</th>
|
||
<th class="ta-c">Risk</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@for (k of kc2; track k.ucic) {
|
||
<tr>
|
||
<td class="ta-c">{{ k.reportRefNo }}</td>
|
||
<td class="mono">{{ k.ucic }}</td>
|
||
<td>{{ k.entityName }}</td>
|
||
<td class="mono">{{ k.panNumber }}</td>
|
||
<td class="mono">{{ k.gstin }}</td>
|
||
<td>{{ k.city }}, {{ k.state }}</td>
|
||
<td>{{ k.customerType }}</td>
|
||
<td>{{ k.isSoleProprietor ? k.ownerName : '—' }}</td>
|
||
<td class="ta-c">
|
||
<span class="risk-tag" [class]="'rk-tag-' + k.riskLevel.toLowerCase()">{{ k.riskLevel }}</span>
|
||
</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- FINNET FILES -->
|
||
@if (activeTab === 'files') {
|
||
<div class="fiu-section">
|
||
<div class="fiu-form-meta">
|
||
<div class="fiu-form-title">
|
||
<h3>FINnet 2.0 Submission Files</h3>
|
||
<p>6 CSV files in FIU-IND prescribed schema, plus STR XML</p>
|
||
</div>
|
||
<button class="fiu-btn fiu-btn-xls" (click)="exportAll()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download All
|
||
</button>
|
||
</div>
|
||
|
||
<div class="files-grid">
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>TC1.csv</div>
|
||
<p>ATM / card transaction template (header only — no card txns this cycle)</p>
|
||
<button class="fiu-btn" (click)="exportTc1()"><fa-icon icon="file-csv"></fa-icon> Download</button>
|
||
</div>
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>TC2.csv</div>
|
||
<p>Branch / cash transactions ({{ ctrTxns.length }} rows)</p>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportTc2()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download
|
||
</button>
|
||
</div>
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>KC1.csv</div>
|
||
<p>Individual customer cards ({{ kc1.length }} rows)</p>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportKc1()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download
|
||
</button>
|
||
</div>
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>KC2.csv</div>
|
||
<p>Entity customer cards ({{ kc2.length }} rows)</p>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportKc2()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download
|
||
</button>
|
||
</div>
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>Account_Detail.csv</div>
|
||
<p>Per-account 12-month aggregates derived from CTR list</p>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportAccountDetail()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download
|
||
</button>
|
||
</div>
|
||
<div class="file-card">
|
||
<div class="file-card-h"><fa-icon icon="file-csv"></fa-icon>Account_Person_Relation.csv</div>
|
||
<p>Account ↔ customer relationship mapping</p>
|
||
<button class="fiu-btn fiu-btn-csv" (click)="exportAccountPersonRelation()">
|
||
<fa-icon icon="file-csv"></fa-icon> Download
|
||
</button>
|
||
</div>
|
||
<div class="file-card file-card--xml">
|
||
<div class="file-card-h"><fa-icon icon="file-alt"></fa-icon>STR.xml</div>
|
||
<p>Suspicious Transaction Report ({{ filedStr + pendingStr }} suspects)</p>
|
||
<button class="fiu-btn fiu-btn-xml" (click)="exportStrXml()">
|
||
<fa-icon icon="file-alt"></fa-icon> Download XML
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="fiu-note">
|
||
<fa-icon icon="info-circle"></fa-icon>
|
||
<span
|
||
><strong>Note:</strong> Files are emitted in FIU-IND FINnet 2.0 CSV schema. Submit via the FINnet portal under
|
||
{{ bank.principalOfficer }}'s digital signature. CTR is due by the 15th of the following month; STR within 7
|
||
days of detection.</span
|
||
>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
<!-- TOAST -->
|
||
<div class="fiu-toast" [class.show]="toastVisible">{{ toastMsg }}</div>
|
||
</div>
|