feat(fiu): add Head Office / Branch-wise scoping; remove reconciliation nav dots
FIU: adds a branch selector (Head Office sees all/drills into one branch, a branch-level login is locked to its own branch) scoping the CTR/STR tabs, dashboard KPIs and header. A FIU_BRANCH_CODE_TO_CANONICAL map bridges the module's internal FINnet branch codes to the app-wide BranchMaster codes. Live backend-driven AML alerts/cases are unchanged (no branch field to scope by). Shell: removes the "working nav" green-dot indicator from the Reconciliation mega-menu's 17 report links per request.
This commit is contained in:
@@ -13,9 +13,12 @@ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
import { AmlService } from 'app/aml/aml.service';
|
||||
import { AuthenticationService } from 'app/core/authentication/authentication.service';
|
||||
import {
|
||||
BRANCHES,
|
||||
BranchMaster,
|
||||
CtrTransaction,
|
||||
CTR_TXNS,
|
||||
FIU_BANK,
|
||||
FIU_BRANCH_CODE_TO_CANONICAL,
|
||||
KC1_INDIVIDUALS,
|
||||
KC2_ENTITIES,
|
||||
KycEntity,
|
||||
@@ -51,6 +54,19 @@ export class FiuComponent implements OnInit {
|
||||
kc1: KycIndividual[] = KC1_INDIVIDUALS;
|
||||
kc2: KycEntity[] = KC2_ENTITIES;
|
||||
|
||||
// -------------------- Head Office vs Branch scope --------------------
|
||||
// CTR/STR filing itself is a bank-wide Principal-Officer function (one filing for the whole
|
||||
// bank, not per branch), but the underlying cash transactions a branch's own staff work
|
||||
// (evidence capture, referral) are still branch-attributable — scoped the same way every other
|
||||
// report in the app splits Head Office (sees everything, can drill into one branch) vs a
|
||||
// branch-level login (locked to its own branch).
|
||||
readonly branches = BRANCHES;
|
||||
isHeadOffice = false;
|
||||
currentOfficeName = 'Branch Office';
|
||||
private ownBranchCode: string | null = null;
|
||||
/** '' = All Branches (Head Office consolidated view); otherwise a BranchMaster.code. */
|
||||
branchFilter = '';
|
||||
|
||||
/** CTR filters */
|
||||
ctrFilterMode: '' | 'Deposit' | 'Withdrawal' = '';
|
||||
ctrFilterAccount = '';
|
||||
@@ -223,6 +239,18 @@ export class FiuComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const creds = this.authenticationService.getCredentials();
|
||||
this.isHeadOffice = this.authenticationService.isHeadOfficeUser();
|
||||
this.currentOfficeName = creds?.officeName || 'Branch Office';
|
||||
if (this.isHeadOffice) {
|
||||
this.branchFilter = '';
|
||||
} else {
|
||||
this.ownBranchCode =
|
||||
this.branches.find((b: BranchMaster) => this.currentOfficeName.toLowerCase().includes(b.name.toLowerCase()))
|
||||
?.code || null;
|
||||
this.branchFilter = this.ownBranchCode || this.branches[0].code;
|
||||
}
|
||||
|
||||
this.loadAmlAlerts();
|
||||
this.loadAmlCtrReports();
|
||||
this.loadAmlStrCases();
|
||||
@@ -614,21 +642,21 @@ export class FiuComponent implements OnInit {
|
||||
|
||||
// -------------------- KPIs --------------------
|
||||
get totalReports(): number {
|
||||
return new Set(this.ctrTxns.map((t) => t.reportRefNo)).size;
|
||||
return new Set(this.scopedCtrTxns.map((t) => t.reportRefNo)).size;
|
||||
}
|
||||
get totalCtrTxns(): number {
|
||||
return this.ctrTxns.length;
|
||||
return this.scopedCtrTxns.length;
|
||||
}
|
||||
get totalCtrAmount(): number {
|
||||
return this.ctrTxns.reduce((s, t) => s + t.txnAmount, 0);
|
||||
return this.scopedCtrTxns.reduce((s, t) => s + t.txnAmount, 0);
|
||||
}
|
||||
get pendingStr(): number {
|
||||
return this.strTxns.filter(
|
||||
return this.scopedStrTxns.filter(
|
||||
(s) => s.status === 'draft' || s.status === 'po-review' || s.status === 'awaiting-filing'
|
||||
).length;
|
||||
}
|
||||
get filedStr(): number {
|
||||
return this.strTxns.filter((s) => s.status === 'filed').length;
|
||||
return this.scopedStrTxns.filter((s) => s.status === 'filed').length;
|
||||
}
|
||||
|
||||
// ── Live STR case counts (backend `amlStrCases`) — these are the cases the
|
||||
@@ -671,10 +699,48 @@ export class FiuComponent implements OnInit {
|
||||
return this.amlAlerts.filter((a) => !ctrRuleCodes.includes(a.ruleCode));
|
||||
}
|
||||
|
||||
// -------------------- Head Office vs Branch scope --------------------
|
||||
/** Maps a FINnet-style internal branch code to the app-wide canonical branch code. */
|
||||
private canonicalBranchOf(branchCode: string): string | undefined {
|
||||
return FIU_BRANCH_CODE_TO_CANONICAL[branchCode];
|
||||
}
|
||||
|
||||
/** Branch name for a row's raw FINnet branch code, for display alongside the code itself. */
|
||||
branchNameFor(branchCode: string): string {
|
||||
const canonical = this.canonicalBranchOf(branchCode);
|
||||
return this.branches.find((b) => b.code === canonical)?.name || '';
|
||||
}
|
||||
|
||||
setBranch(code: string): void {
|
||||
this.branchFilter = code;
|
||||
}
|
||||
|
||||
/** Name of the branch/scope currently being viewed, for display in the header. */
|
||||
get scopeName(): string {
|
||||
if (!this.isHeadOffice) {
|
||||
return this.currentOfficeName;
|
||||
}
|
||||
return this.branchFilter
|
||||
? this.branches.find((b) => b.code === this.branchFilter)?.name || ''
|
||||
: 'All Branches (Consolidated)';
|
||||
}
|
||||
|
||||
get scopedCtrTxns(): CtrTransaction[] {
|
||||
return this.branchFilter
|
||||
? this.ctrTxns.filter((t) => this.canonicalBranchOf(t.branchCode) === this.branchFilter)
|
||||
: this.ctrTxns;
|
||||
}
|
||||
|
||||
get scopedStrTxns(): StrTransaction[] {
|
||||
return this.branchFilter
|
||||
? this.strTxns.filter((s) => this.canonicalBranchOf(s.branchCode) === this.branchFilter)
|
||||
: this.strTxns;
|
||||
}
|
||||
|
||||
// -------------------- Filtered lists --------------------
|
||||
get filteredCtr(): CtrTransaction[] {
|
||||
const acc = this.ctrFilterAccount.trim();
|
||||
return this.ctrTxns.filter((t) => {
|
||||
return this.scopedCtrTxns.filter((t) => {
|
||||
if (this.ctrFilterMode && t.depositOrWithdrawal !== this.ctrFilterMode) return false;
|
||||
if (acc && !t.accountNumber.includes(acc)) return false;
|
||||
if (this.ctrFilterMinAmount > 0 && t.txnAmount < this.ctrFilterMinAmount) return false;
|
||||
@@ -683,7 +749,7 @@ export class FiuComponent implements OnInit {
|
||||
}
|
||||
|
||||
get filteredStr(): StrTransaction[] {
|
||||
return this.strTxns.filter((s) => {
|
||||
return this.scopedStrTxns.filter((s) => {
|
||||
if (this.strFilterStatus && s.status !== this.strFilterStatus) return false;
|
||||
if (this.strFilterRisk && s.riskCategory !== this.strFilterRisk) return false;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user