- Add /digital/neft-rtgs (entry) and /digital/neft-rtgs-report (analytics): KPIs, tabbed views (Trends, Bank-wise, Date-wise, Pending/Pass/Return, Branch/Mobile, User-wise), filterable transaction table with CSV export, and a non-dismissible Initiate dialog launched from a floating action. - Make BANL verification mandatory before NEFT/RTGS submit; auto-fill and lock beneficiary name from the lookup response, invalidate match on A/C or IFSC edit, demo fallback for unknown accounts. - Add Digital menu links (NEFT/RTGS + Report) in shell top-nav. - Replace toolbar theme toggle with AI / Intelligence Modules mega menu: 4 colour-coded columns covering Lending & Risk, Investment & Profit, Compliance & Advisory, Governance (9 modules total). Wire RBI Notifications Monitoring to /rbi-circulars. - Unify notifications, settings, AI, and profile toolbar buttons into a 26px ring style; colourful gradient bell SVG for notifications, custom gear+petals AI mark, online dot on the avatar. - Trim ISO 27001 chip in the top bar. - Add MPL header to generated .env.ts and its template in version.js. - Bundles other pending working-tree changes (clients family/nominee tab tweaks, auth/2FA fixes, translations) into the same push. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
748 lines
23 KiB
TypeScript
748 lines
23 KiB
TypeScript
/**
|
|
* 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/.
|
|
*/
|
|
|
|
import { Component, inject, OnInit } from '@angular/core';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
import { MatTooltip } from '@angular/material/tooltip';
|
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|
|
|
import { NeftRtgsEntryComponent } from '../neft-rtgs-entry/neft-rtgs-entry.component';
|
|
|
|
export type PaymentType = 'NEFT' | 'RTGS';
|
|
export type ProcessingState = 'UPLOADED' | 'VALIDATED' | 'SENT' | 'SETTLED' | 'PENDING' | 'RETURNED';
|
|
|
|
export interface NeftRtgsTxn {
|
|
batchId: string;
|
|
instructionId: string;
|
|
utrNumber: string;
|
|
remitterAcc: string;
|
|
remitterBranch: string;
|
|
remitterUser: string;
|
|
remitterChannel: 'BRANCH' | 'MOBILE';
|
|
beneAcc: string;
|
|
beneIfsc: string;
|
|
beneName: string;
|
|
beneBank: string;
|
|
paymentType: PaymentType;
|
|
amount: number;
|
|
valueDate: string; // YYYY-MM-DD
|
|
purposeCode: string;
|
|
leiCode?: string;
|
|
processingState: ProcessingState;
|
|
returnCode?: string;
|
|
returnReason?: string;
|
|
sentTimestamp: string; // YYYY-MM-DD HH:mm:ss
|
|
}
|
|
|
|
type ReportTab = 'trends' | 'bank' | 'date' | 'pending' | 'channel' | 'user';
|
|
|
|
interface BankRow {
|
|
bank: string;
|
|
count: number;
|
|
amount: number;
|
|
settled: number;
|
|
pending: number;
|
|
returned: number;
|
|
}
|
|
|
|
interface DateRow {
|
|
date: string;
|
|
count: number;
|
|
amount: number;
|
|
neft: number;
|
|
rtgs: number;
|
|
}
|
|
|
|
interface UserRow {
|
|
user: string;
|
|
count: number;
|
|
amount: number;
|
|
branch: string;
|
|
}
|
|
|
|
interface ChannelRow {
|
|
channel: 'BRANCH' | 'MOBILE';
|
|
count: number;
|
|
amount: number;
|
|
share: number;
|
|
}
|
|
|
|
@Component({
|
|
selector: 'mifosx-neft-rtgs-report',
|
|
templateUrl: './neft-rtgs-report.component.html',
|
|
styleUrls: ['./neft-rtgs-report.component.scss'],
|
|
imports: [
|
|
...STANDALONE_SHARED_IMPORTS,
|
|
FormsModule,
|
|
FaIconComponent,
|
|
MatTooltip
|
|
]
|
|
})
|
|
export class NeftRtgsReportComponent implements OnInit {
|
|
private dialog = inject(MatDialog);
|
|
|
|
/** Active tab */
|
|
activeTab: ReportTab = 'trends';
|
|
|
|
/** Search / filter */
|
|
search = '';
|
|
typeFilter: '' | PaymentType = '';
|
|
stateFilter: '' | ProcessingState = '';
|
|
|
|
/** All transactions (mock data — replace with API). */
|
|
txns: NeftRtgsTxn[] = [];
|
|
|
|
/** Tab labels */
|
|
readonly tabs: { id: ReportTab; label: string; icon: string }[] = [
|
|
{ id: 'trends', label: 'Trends', icon: 'chart-line' },
|
|
{ id: 'bank', label: 'Bank-wise', icon: 'university' },
|
|
{ id: 'date', label: 'Date-wise', icon: 'calendar-alt' },
|
|
{ id: 'pending', label: 'Pending / Pass / Return', icon: 'tasks' },
|
|
{ id: 'channel', label: 'Branch / Mobile', icon: 'mobile-alt' },
|
|
{ id: 'user', label: 'User-wise', icon: 'user-tie' }
|
|
];
|
|
|
|
ngOnInit(): void {
|
|
this.txns = this.seedTransactions();
|
|
}
|
|
|
|
// ───────────────────── KPIs ─────────────────────
|
|
get totalCount(): number {
|
|
return this.txns.length;
|
|
}
|
|
get totalAmount(): number {
|
|
return this.txns.reduce((s, t) => s + t.amount, 0);
|
|
}
|
|
get settledCount(): number {
|
|
return this.txns.filter((t) => t.processingState === 'SETTLED').length;
|
|
}
|
|
get pendingCount(): number {
|
|
return this.txns.filter((t) => [
|
|
'UPLOADED',
|
|
'VALIDATED',
|
|
'SENT',
|
|
'PENDING'
|
|
].includes(t.processingState)).length;
|
|
}
|
|
get returnedCount(): number {
|
|
return this.txns.filter((t) => t.processingState === 'RETURNED').length;
|
|
}
|
|
get neftCount(): number {
|
|
return this.txns.filter((t) => t.paymentType === 'NEFT').length;
|
|
}
|
|
get rtgsCount(): number {
|
|
return this.txns.filter((t) => t.paymentType === 'RTGS').length;
|
|
}
|
|
get neftAmount(): number {
|
|
return this.txns.filter((t) => t.paymentType === 'NEFT').reduce((s, t) => s + t.amount, 0);
|
|
}
|
|
get rtgsAmount(): number {
|
|
return this.txns.filter((t) => t.paymentType === 'RTGS').reduce((s, t) => s + t.amount, 0);
|
|
}
|
|
get successRate(): number {
|
|
if (this.totalCount === 0) return 0;
|
|
return (this.settledCount / this.totalCount) * 100;
|
|
}
|
|
get avgTicket(): number {
|
|
if (this.totalCount === 0) return 0;
|
|
return this.totalAmount / this.totalCount;
|
|
}
|
|
|
|
// ───────────────────── Filtered list ─────────────────────
|
|
get filteredTxns(): NeftRtgsTxn[] {
|
|
const q = this.search.trim().toLowerCase();
|
|
return this.txns.filter((t) => {
|
|
if (this.typeFilter && t.paymentType !== this.typeFilter) return false;
|
|
if (this.stateFilter && t.processingState !== this.stateFilter) return false;
|
|
if (!q) return true;
|
|
return (
|
|
t.utrNumber.toLowerCase().includes(q) ||
|
|
t.batchId.toLowerCase().includes(q) ||
|
|
t.instructionId.toLowerCase().includes(q) ||
|
|
t.beneAcc.toLowerCase().includes(q) ||
|
|
t.beneIfsc.toLowerCase().includes(q) ||
|
|
t.beneName.toLowerCase().includes(q) ||
|
|
t.remitterAcc.toLowerCase().includes(q)
|
|
);
|
|
});
|
|
}
|
|
|
|
// ───────────────────── Tab-specific aggregations ─────────────────────
|
|
get bankRows(): BankRow[] {
|
|
const map = new Map<string, BankRow>();
|
|
for (const t of this.txns) {
|
|
const key = t.beneBank;
|
|
if (!map.has(key)) {
|
|
map.set(key, { bank: key, count: 0, amount: 0, settled: 0, pending: 0, returned: 0 });
|
|
}
|
|
const r = map.get(key)!;
|
|
r.count++;
|
|
r.amount += t.amount;
|
|
if (t.processingState === 'SETTLED') r.settled++;
|
|
else if (t.processingState === 'RETURNED') r.returned++;
|
|
else r.pending++;
|
|
}
|
|
return Array.from(map.values()).sort((a, b) => b.amount - a.amount);
|
|
}
|
|
|
|
get dateRows(): DateRow[] {
|
|
const map = new Map<string, DateRow>();
|
|
for (const t of this.txns) {
|
|
if (!map.has(t.valueDate)) {
|
|
map.set(t.valueDate, { date: t.valueDate, count: 0, amount: 0, neft: 0, rtgs: 0 });
|
|
}
|
|
const r = map.get(t.valueDate)!;
|
|
r.count++;
|
|
r.amount += t.amount;
|
|
if (t.paymentType === 'NEFT') r.neft++;
|
|
else r.rtgs++;
|
|
}
|
|
return Array.from(map.values()).sort((a, b) => (a.date < b.date ? 1 : -1));
|
|
}
|
|
|
|
get userRows(): UserRow[] {
|
|
const map = new Map<string, UserRow>();
|
|
for (const t of this.txns) {
|
|
const key = `${t.remitterUser}|${t.remitterBranch}`;
|
|
if (!map.has(key)) {
|
|
map.set(key, { user: t.remitterUser, branch: t.remitterBranch, count: 0, amount: 0 });
|
|
}
|
|
const r = map.get(key)!;
|
|
r.count++;
|
|
r.amount += t.amount;
|
|
}
|
|
return Array.from(map.values()).sort((a, b) => b.amount - a.amount);
|
|
}
|
|
|
|
get channelRows(): ChannelRow[] {
|
|
const total = this.totalAmount || 1;
|
|
const map = new Map<'BRANCH' | 'MOBILE', ChannelRow>();
|
|
for (const t of this.txns) {
|
|
if (!map.has(t.remitterChannel)) {
|
|
map.set(t.remitterChannel, {
|
|
channel: t.remitterChannel,
|
|
count: 0,
|
|
amount: 0,
|
|
share: 0
|
|
});
|
|
}
|
|
const r = map.get(t.remitterChannel)!;
|
|
r.count++;
|
|
r.amount += t.amount;
|
|
}
|
|
map.forEach((r) => (r.share = (r.amount / total) * 100));
|
|
return Array.from(map.values());
|
|
}
|
|
|
|
/** Trend buckets — last 7 value-dates */
|
|
get trendBuckets(): DateRow[] {
|
|
return this.dateRows.slice(0, 7).reverse();
|
|
}
|
|
|
|
/** Max amount across trend buckets (for bar chart scaling). */
|
|
get trendMaxAmount(): number {
|
|
const buckets = this.trendBuckets;
|
|
if (!buckets.length) return 1;
|
|
return Math.max(...buckets.map((b) => b.amount));
|
|
}
|
|
|
|
/** Return-code breakdown for Pending/Pass/Return tab */
|
|
get returnCodeRows(): { code: string; reason: string; count: number; amount: number }[] {
|
|
const map = new Map<string, { code: string; reason: string; count: number; amount: number }>();
|
|
for (const t of this.txns) {
|
|
if (t.processingState !== 'RETURNED' || !t.returnCode) continue;
|
|
if (!map.has(t.returnCode)) {
|
|
map.set(t.returnCode, {
|
|
code: t.returnCode,
|
|
reason: t.returnReason || '',
|
|
count: 0,
|
|
amount: 0
|
|
});
|
|
}
|
|
const r = map.get(t.returnCode)!;
|
|
r.count++;
|
|
r.amount += t.amount;
|
|
}
|
|
return Array.from(map.values()).sort((a, b) => b.count - a.count);
|
|
}
|
|
|
|
// ───────────────────── Actions ─────────────────────
|
|
showTab(tab: ReportTab): void {
|
|
this.activeTab = tab;
|
|
}
|
|
|
|
/** Floating action — open NEFT/RTGS entry in a non-dismissible dialog. */
|
|
openInitiateDialog(): void {
|
|
const ref = this.dialog.open(NeftRtgsEntryComponent, {
|
|
width: '880px',
|
|
maxWidth: '94vw',
|
|
maxHeight: '88vh',
|
|
disableClose: true,
|
|
autoFocus: false,
|
|
restoreFocus: true,
|
|
panelClass: 'nr-entry-dialog',
|
|
backdropClass: 'nr-entry-backdrop'
|
|
});
|
|
ref.afterClosed().subscribe((result) => {
|
|
if (result && result.submitted && result.payload) {
|
|
this.txns = [
|
|
this.toTxn(result.payload),
|
|
...this.txns
|
|
];
|
|
}
|
|
});
|
|
}
|
|
|
|
exportCsv(): void {
|
|
const headers = [
|
|
'Batch ID',
|
|
'Instruction ID',
|
|
'UTR Number',
|
|
'Remitter Acc',
|
|
'Bene Acc No',
|
|
'Bene IFSC',
|
|
'Bene Name',
|
|
'Payment Type',
|
|
'Amount',
|
|
'Value Date',
|
|
'Purpose Code',
|
|
'LEI Code',
|
|
'Processing State',
|
|
'Return Code',
|
|
'Sent Timestamp'
|
|
];
|
|
const rows: string[][] = [headers];
|
|
for (const t of this.filteredTxns) {
|
|
rows.push([
|
|
t.batchId,
|
|
t.instructionId,
|
|
t.utrNumber,
|
|
t.remitterAcc,
|
|
t.beneAcc,
|
|
t.beneIfsc,
|
|
t.beneName,
|
|
t.paymentType,
|
|
t.amount.toFixed(2),
|
|
t.valueDate,
|
|
t.purposeCode,
|
|
t.leiCode || '',
|
|
t.processingState,
|
|
t.returnCode || '',
|
|
t.sentTimestamp
|
|
]);
|
|
}
|
|
const escape = (v: string): string => {
|
|
const s = (v || '').replace(/"/g, '""');
|
|
return /[,"\n]/.test(s) ? `"${s}"` : s;
|
|
};
|
|
const csv = rows.map((r) => r.map(escape).join(',')).join('\n') + '\n';
|
|
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = `NEFT_RTGS_Report_${new Date().toISOString().slice(0, 10)}.csv`;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
clearFilters(): void {
|
|
this.search = '';
|
|
this.typeFilter = '';
|
|
this.stateFilter = '';
|
|
}
|
|
|
|
// ───────────────────── Helpers ─────────────────────
|
|
stateColor(state: ProcessingState): string {
|
|
switch (state) {
|
|
case 'SETTLED':
|
|
return 'green';
|
|
case 'RETURNED':
|
|
return 'red';
|
|
case 'SENT':
|
|
return 'blue';
|
|
case 'VALIDATED':
|
|
return 'teal';
|
|
case 'UPLOADED':
|
|
return 'amber';
|
|
case 'PENDING':
|
|
return 'amber';
|
|
}
|
|
}
|
|
|
|
trendBarHeight(amount: number): number {
|
|
return Math.max(6, Math.round((amount / this.trendMaxAmount) * 100));
|
|
}
|
|
|
|
/** Convert a submitted entry-form payload into a synthetic transaction row. */
|
|
private toTxn(p: any): NeftRtgsTxn {
|
|
const valueDate = p.valueDate
|
|
? new Date(p.valueDate).toISOString().slice(0, 10)
|
|
: new Date().toISOString().slice(0, 10);
|
|
const ts = new Date();
|
|
const pad = (n: number) => String(n).padStart(2, '0');
|
|
return {
|
|
batchId: `H2H-${valueDate.replace(/-/g, '')}-${pad(Math.floor(Math.random() * 99) + 1)}`,
|
|
instructionId: 'ERP' + Date.now().toString().slice(-8),
|
|
utrNumber: 'KKBK' + Date.now().toString().slice(-11),
|
|
remitterAcc: p.senderAccount || '',
|
|
remitterBranch: 'Main Branch',
|
|
remitterUser: 'Current User',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: p.beneficiaryAccount || '',
|
|
beneIfsc: (p.ifscCode || '').toUpperCase(),
|
|
beneName: p.beneficiaryName || '',
|
|
beneBank: this.bankFromIfsc(p.ifscCode || ''),
|
|
paymentType: p.transactionType,
|
|
amount: Number(p.amount) || 0,
|
|
valueDate,
|
|
purposeCode: this.purposeCodeFor(p.purposeOfRemittance),
|
|
leiCode: Number(p.amount) >= 500000000 ? '549300ABCDEF1234' : undefined,
|
|
processingState: 'UPLOADED',
|
|
sentTimestamp:
|
|
ts.getFullYear() +
|
|
'-' +
|
|
pad(ts.getMonth() + 1) +
|
|
'-' +
|
|
pad(ts.getDate()) +
|
|
' ' +
|
|
pad(ts.getHours()) +
|
|
':' +
|
|
pad(ts.getMinutes()) +
|
|
':' +
|
|
pad(ts.getSeconds())
|
|
};
|
|
}
|
|
|
|
private bankFromIfsc(ifsc: string): string {
|
|
const code = ifsc.slice(0, 4).toUpperCase();
|
|
const map: Record<string, string> = {
|
|
HDFC: 'HDFC Bank',
|
|
ICIC: 'ICICI Bank',
|
|
SBIN: 'State Bank of India',
|
|
KKBK: 'Kotak Mahindra Bank',
|
|
AXIS: 'Axis Bank',
|
|
UTIB: 'Axis Bank',
|
|
PUNB: 'Punjab National Bank',
|
|
BARB: 'Bank of Baroda',
|
|
CNRB: 'Canara Bank',
|
|
YESB: 'YES Bank',
|
|
IDFB: 'IDFC FIRST Bank'
|
|
};
|
|
return map[code] || code + ' Bank';
|
|
}
|
|
|
|
private purposeCodeFor(p: string): string {
|
|
const map: Record<string, string> = {
|
|
CAPITAL_TRANSFER: 'P0102',
|
|
FAMILY_MAINTENANCE: 'P1301',
|
|
TRADE_SETTLEMENT: 'P0801',
|
|
SALARY_PAYMENT: 'P1006',
|
|
LOAN_REPAYMENT: 'P0103',
|
|
TAX_PAYMENT: 'P1099',
|
|
VENDOR_PAYMENT: 'P0802',
|
|
INVESTMENT: 'P0202',
|
|
GIFT: 'P1302',
|
|
OTHER: 'P0099'
|
|
};
|
|
return map[p] || 'P0099';
|
|
}
|
|
|
|
// ───────────────────── Mock seed data ─────────────────────
|
|
private seedTransactions(): NeftRtgsTxn[] {
|
|
const today = new Date();
|
|
const dt = (offset: number, h = 10, m = 0): string => {
|
|
const d = new Date(today);
|
|
d.setDate(d.getDate() - offset);
|
|
const pad = (n: number) => String(n).padStart(2, '0');
|
|
return (
|
|
d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(h) + ':' + pad(m) + ':00'
|
|
);
|
|
};
|
|
const vd = (offset: number): string => dt(offset).slice(0, 10);
|
|
|
|
return [
|
|
{
|
|
batchId: 'H2H-20260326-01',
|
|
instructionId: 'ERP77889922',
|
|
utrNumber: 'KKBKR5202608511',
|
|
remitterAcc: '50200012345678',
|
|
remitterBranch: 'Mumbai — BKC',
|
|
remitterUser: 'Anita Desai',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '91000222333444',
|
|
beneIfsc: 'HDFC0001234',
|
|
beneName: 'Global Logistics Ltd',
|
|
beneBank: 'HDFC Bank',
|
|
paymentType: 'RTGS',
|
|
amount: 550000,
|
|
valueDate: vd(0),
|
|
purposeCode: 'P0102',
|
|
leiCode: '549300ABCDEF1234',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(0, 14, 5)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260326-01',
|
|
instructionId: 'ERP77889923',
|
|
utrNumber: 'HDFCR5202608712',
|
|
remitterAcc: '50200012345678',
|
|
remitterBranch: 'Mumbai — BKC',
|
|
remitterUser: 'Anita Desai',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '345678901234',
|
|
beneIfsc: 'ICIC0000567',
|
|
beneName: 'Bluestone Trading Co.',
|
|
beneBank: 'ICICI Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 78500,
|
|
valueDate: vd(0),
|
|
purposeCode: 'P0802',
|
|
processingState: 'SENT',
|
|
sentTimestamp: dt(0, 14, 6)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260325-04',
|
|
instructionId: 'ERP77889811',
|
|
utrNumber: 'SBINR5202608902',
|
|
remitterAcc: '50200099887766',
|
|
remitterBranch: 'Bengaluru — MG Road',
|
|
remitterUser: 'Karthik Rao',
|
|
remitterChannel: 'MOBILE',
|
|
beneAcc: '912345678901',
|
|
beneIfsc: 'SBIN0011223',
|
|
beneName: 'Anita Verma',
|
|
beneBank: 'State Bank of India',
|
|
paymentType: 'NEFT',
|
|
amount: 15000,
|
|
valueDate: vd(1),
|
|
purposeCode: 'P1301',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(1, 11, 22)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260325-04',
|
|
instructionId: 'ERP77889812',
|
|
utrNumber: 'AXISR5202608811',
|
|
remitterAcc: '50200099887766',
|
|
remitterBranch: 'Bengaluru — MG Road',
|
|
remitterUser: 'Karthik Rao',
|
|
remitterChannel: 'MOBILE',
|
|
beneAcc: '6789012345',
|
|
beneIfsc: 'UTIB0000456',
|
|
beneName: 'Rakesh Industries',
|
|
beneBank: 'Axis Bank',
|
|
paymentType: 'RTGS',
|
|
amount: 1250000,
|
|
valueDate: vd(1),
|
|
purposeCode: 'P0801',
|
|
leiCode: '549300XYZAB7890',
|
|
processingState: 'RETURNED',
|
|
returnCode: 'R01',
|
|
returnReason: 'Insufficient Funds',
|
|
sentTimestamp: dt(1, 11, 25)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260324-02',
|
|
instructionId: 'ERP77889701',
|
|
utrNumber: 'PUNBR5202608619',
|
|
remitterAcc: '50100221122334',
|
|
remitterBranch: 'Delhi — Connaught',
|
|
remitterUser: 'Sushma Iyer',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '50100998877665',
|
|
beneIfsc: 'PUNB0123400',
|
|
beneName: 'Madhavi Singh',
|
|
beneBank: 'Punjab National Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 42000,
|
|
valueDate: vd(2),
|
|
purposeCode: 'P1006',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(2, 9, 35)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260324-02',
|
|
instructionId: 'ERP77889702',
|
|
utrNumber: 'YESBR5202608520',
|
|
remitterAcc: '50100221122334',
|
|
remitterBranch: 'Delhi — Connaught',
|
|
remitterUser: 'Sushma Iyer',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '11223344556677',
|
|
beneIfsc: 'YESB0000123',
|
|
beneName: 'Sigma Constructions',
|
|
beneBank: 'YES Bank',
|
|
paymentType: 'RTGS',
|
|
amount: 825000,
|
|
valueDate: vd(2),
|
|
purposeCode: 'P0102',
|
|
processingState: 'PENDING',
|
|
sentTimestamp: dt(2, 9, 38)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260323-07',
|
|
instructionId: 'ERP77889601',
|
|
utrNumber: 'CNRBR5202608417',
|
|
remitterAcc: '50100887766554',
|
|
remitterBranch: 'Chennai — T. Nagar',
|
|
remitterUser: 'Ramesh Krishnan',
|
|
remitterChannel: 'MOBILE',
|
|
beneAcc: '99887766554433',
|
|
beneIfsc: 'CNRB0001890',
|
|
beneName: 'Padma Rao',
|
|
beneBank: 'Canara Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 9800,
|
|
valueDate: vd(3),
|
|
purposeCode: 'P1302',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(3, 16, 15)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260323-07',
|
|
instructionId: 'ERP77889602',
|
|
utrNumber: 'BARBR5202608318',
|
|
remitterAcc: '50100887766554',
|
|
remitterBranch: 'Chennai — T. Nagar',
|
|
remitterUser: 'Ramesh Krishnan',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '50100123456987',
|
|
beneIfsc: 'BARB0VJVATA',
|
|
beneName: 'Vijaya Traders',
|
|
beneBank: 'Bank of Baroda',
|
|
paymentType: 'NEFT',
|
|
amount: 125000,
|
|
valueDate: vd(3),
|
|
purposeCode: 'P0802',
|
|
processingState: 'VALIDATED',
|
|
sentTimestamp: dt(3, 16, 20)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260322-03',
|
|
instructionId: 'ERP77889501',
|
|
utrNumber: 'IDFBR5202608215',
|
|
remitterAcc: '50200445566778',
|
|
remitterBranch: 'Pune — Koregaon Park',
|
|
remitterUser: 'Vikram Joshi',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '70010023456789',
|
|
beneIfsc: 'IDFB0040101',
|
|
beneName: 'Pinnacle Realty Pvt Ltd',
|
|
beneBank: 'IDFC FIRST Bank',
|
|
paymentType: 'RTGS',
|
|
amount: 3450000,
|
|
valueDate: vd(4),
|
|
purposeCode: 'P0202',
|
|
leiCode: '549300QRSTUV5678',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(4, 12, 45)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260322-03',
|
|
instructionId: 'ERP77889502',
|
|
utrNumber: 'HDFCR5202608116',
|
|
remitterAcc: '50200445566778',
|
|
remitterBranch: 'Pune — Koregaon Park',
|
|
remitterUser: 'Vikram Joshi',
|
|
remitterChannel: 'MOBILE',
|
|
beneAcc: '50100654321789',
|
|
beneIfsc: 'HDFC0009876',
|
|
beneName: 'Neha Kapoor',
|
|
beneBank: 'HDFC Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 25000,
|
|
valueDate: vd(4),
|
|
purposeCode: 'P1301',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(4, 12, 50)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260321-05',
|
|
instructionId: 'ERP77889411',
|
|
utrNumber: 'KKBKR5202608013',
|
|
remitterAcc: '50200778899001',
|
|
remitterBranch: 'Hyderabad — Banjara',
|
|
remitterUser: 'Lakshmi Naidu',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '12345678900011',
|
|
beneIfsc: 'KKBK0001899',
|
|
beneName: 'Aarav Enterprises',
|
|
beneBank: 'Kotak Mahindra Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 67000,
|
|
valueDate: vd(5),
|
|
purposeCode: 'P0802',
|
|
processingState: 'RETURNED',
|
|
returnCode: 'R03',
|
|
returnReason: 'Account Closed',
|
|
sentTimestamp: dt(5, 10, 5)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260321-05',
|
|
instructionId: 'ERP77889412',
|
|
utrNumber: 'SBINR5202607914',
|
|
remitterAcc: '50200778899001',
|
|
remitterBranch: 'Hyderabad — Banjara',
|
|
remitterUser: 'Lakshmi Naidu',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '50100445566778',
|
|
beneIfsc: 'SBIN0008765',
|
|
beneName: 'Spectra Components',
|
|
beneBank: 'State Bank of India',
|
|
paymentType: 'RTGS',
|
|
amount: 980000,
|
|
valueDate: vd(5),
|
|
purposeCode: 'P0801',
|
|
leiCode: '549300LMNOPQ2468',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(5, 10, 10)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260320-06',
|
|
instructionId: 'ERP77889301',
|
|
utrNumber: 'ICICR5202607812',
|
|
remitterAcc: '50100334455667',
|
|
remitterBranch: 'Kolkata — Park Street',
|
|
remitterUser: 'Arjun Banerjee',
|
|
remitterChannel: 'MOBILE',
|
|
beneAcc: '88990011223344',
|
|
beneIfsc: 'ICIC0001234',
|
|
beneName: 'Eastern Logistics',
|
|
beneBank: 'ICICI Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 188000,
|
|
valueDate: vd(6),
|
|
purposeCode: 'P0802',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(6, 14, 30)
|
|
},
|
|
{
|
|
batchId: 'H2H-20260320-06',
|
|
instructionId: 'ERP77889302',
|
|
utrNumber: 'AXISR5202607711',
|
|
remitterAcc: '50100334455667',
|
|
remitterBranch: 'Kolkata — Park Street',
|
|
remitterUser: 'Arjun Banerjee',
|
|
remitterChannel: 'BRANCH',
|
|
beneAcc: '50200998877665',
|
|
beneIfsc: 'UTIB0001234',
|
|
beneName: 'Indrani Sen',
|
|
beneBank: 'Axis Bank',
|
|
paymentType: 'NEFT',
|
|
amount: 5500,
|
|
valueDate: vd(6),
|
|
purposeCode: 'P1302',
|
|
processingState: 'SETTLED',
|
|
sentTimestamp: dt(6, 14, 32)
|
|
}
|
|
];
|
|
}
|
|
}
|