oss file updated, profitl loss as per the day month and also with date select
This commit is contained in:
+15
@@ -365,6 +365,21 @@
|
||||
</mat-form-field>
|
||||
</form>
|
||||
}
|
||||
|
||||
<!-- Compliance / AML Action Triage -->
|
||||
<div class="compliance-triage" style="margin-top: 16px; padding: 12px; background: #fff8f8; border: 1px dashed #f5c2c2; border-radius: 8px;">
|
||||
<h4 style="margin: 0 0 8px; font-weight: 600; color: #b91c1c; display: flex; align-items: center; gap: 6px;">
|
||||
Compliance & AML Triage
|
||||
</h4>
|
||||
<div style="display: flex; flex-direction: column; gap: 8px;">
|
||||
<mat-checkbox [(ngModel)]="flagAsSuspicious" [ngModelOptions]="{standalone: true}">
|
||||
Flag as suspicious (escalate to STR cases under RBI compliance)
|
||||
</mat-checkbox>
|
||||
<mat-checkbox [(ngModel)]="markAsWhitelisted" [ngModelOptions]="{standalone: true}">
|
||||
Mark as whitelisted (prevent future AML alerts for this account)
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div #lightboxRoot style="display: none"></div>
|
||||
|
||||
+86
@@ -131,6 +131,90 @@ export class ItemDecisionDialogComponent implements OnInit, OnDestroy {
|
||||
/** 'any' = mode of operation lets any one signer sign (Either/Anyone or Survivor); 'all' = every mandatory signer must sign. */
|
||||
signerSelectionMode: 'any' | 'all' = 'any';
|
||||
manualOverrideChecked = false;
|
||||
flagAsSuspicious = false;
|
||||
markAsWhitelisted = false;
|
||||
|
||||
handleComplianceActions(): void {
|
||||
if (this.flagAsSuspicious) {
|
||||
const existingStrData = localStorage.getItem('fiu_str_cases');
|
||||
let cases: any[] = [];
|
||||
if (existingStrData) {
|
||||
try {
|
||||
cases = JSON.parse(existingStrData);
|
||||
} catch (e) {
|
||||
cases = [];
|
||||
}
|
||||
}
|
||||
|
||||
const newRef = 101 + cases.length;
|
||||
const newCase: any = {
|
||||
reportType: 'STR',
|
||||
reportRefNo: newRef,
|
||||
branchCode: this.item.presentingBranchCode || '1',
|
||||
accountNumber: this.item.accountNo || this.item.accountId || '110001101000838',
|
||||
txnBranchCode: this.item.presentingBranchCode || '1',
|
||||
depositOrWithdrawal: 'Withdrawal',
|
||||
txnId: this.item.id,
|
||||
txnDate: new Date().toLocaleDateString('en-GB').replace(/\//g, '-'),
|
||||
txnTime: new Date().toLocaleTimeString('en-US', { hour12: false }),
|
||||
txnAmount: this.item.amount,
|
||||
instrumentType: 'Cheque',
|
||||
instrumentId: this.item.chequeNumber,
|
||||
nonCustomerRef: '',
|
||||
relationshipFlag: 'Customer',
|
||||
thirdPartyPan: '',
|
||||
declaration: 'NA',
|
||||
customerName: this.item.clientName || 'UNKNOWN CLIENT',
|
||||
detectedOn: new Date().toLocaleDateString('en-GB').replace(/\//g, '-'),
|
||||
flaggedBy: 'CTS Clearing Officer',
|
||||
riskCategory: 'unusual-pattern',
|
||||
narrative: `CTS Cheque #${this.item.chequeNumber} for amount ₹${this.item.amount} flagged as suspicious by Clearing Officer during inward presentment review. Action: ${this.mode}. Reason/Notes: ${this.mode === 'RETURN' ? this.returnForm.value.reason : this.passForm.value.note || 'Manual compliance escalation'}`,
|
||||
status: 'po-review'
|
||||
};
|
||||
|
||||
cases.unshift(newCase);
|
||||
localStorage.setItem('fiu_str_cases', JSON.stringify(cases));
|
||||
|
||||
const storedCtr = localStorage.getItem('fiu_ctr_txns');
|
||||
if (storedCtr) {
|
||||
try {
|
||||
const ctrList = JSON.parse(storedCtr);
|
||||
const matching = ctrList.find((t: any) => t.accountNumber === newCase.accountNumber);
|
||||
if (matching) {
|
||||
matching.complianceStatus = 'SUSPICIOUS';
|
||||
localStorage.setItem('fiu_ctr_txns', JSON.stringify(ctrList));
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
} else if (this.markAsWhitelisted) {
|
||||
const existingWhitelist = localStorage.getItem('compliance_whitelisted_accounts');
|
||||
let whitelisted: string[] = [];
|
||||
if (existingWhitelist) {
|
||||
try {
|
||||
whitelisted = JSON.parse(existingWhitelist);
|
||||
} catch (e) {
|
||||
whitelisted = [];
|
||||
}
|
||||
}
|
||||
const account = this.item.accountNo || this.item.accountId;
|
||||
if (account && !whitelisted.includes(account.toString())) {
|
||||
whitelisted.push(account.toString());
|
||||
localStorage.setItem('compliance_whitelisted_accounts', JSON.stringify(whitelisted));
|
||||
}
|
||||
|
||||
const storedCtr = localStorage.getItem('fiu_ctr_txns');
|
||||
if (storedCtr) {
|
||||
try {
|
||||
const ctrList = JSON.parse(storedCtr);
|
||||
const matching = ctrList.find((t: any) => t.accountNumber === (account ? account.toString() : ''));
|
||||
if (matching) {
|
||||
matching.complianceStatus = 'WHITELISTED';
|
||||
localStorage.setItem('fiu_ctr_txns', JSON.stringify(ctrList));
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Every automatic validation rule InwardClearingValidationService already computes, shown so the clerk sees WHY, not just a decision. */
|
||||
readonly validationRules: { key: string; label: string; goodWhenTrue: boolean }[] = [
|
||||
@@ -652,6 +736,7 @@ export class ItemDecisionDialogComponent implements OnInit, OnDestroy {
|
||||
this.ctsService.passInwardItem(this.item.id, payload).subscribe({
|
||||
next: () => {
|
||||
this.busy = false;
|
||||
this.handleComplianceActions();
|
||||
this.notify('Cheque passed');
|
||||
this.dialogRef.close({ actioned: true });
|
||||
},
|
||||
@@ -676,6 +761,7 @@ export class ItemDecisionDialogComponent implements OnInit, OnDestroy {
|
||||
this.ctsService.returnInwardItem(this.item.id, payload).subscribe({
|
||||
next: () => {
|
||||
this.busy = false;
|
||||
this.handleComplianceActions();
|
||||
this.notify('Cheque returned');
|
||||
this.dialogRef.close({ actioned: true });
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user