/** * 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 } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MatTooltip } from '@angular/material/tooltip'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { NeftRtgsTxn, ProcessingState } from '../neft-rtgs-report/neft-rtgs-report.component'; export interface SenderHistoryDialogData { /** Sender's name as shown on the sender chip. */ senderName: string; /** Picked sender account number (for exact-match filtering). */ senderAccountNo: string; /** Full transaction history to filter (already-seeded mock or live API rows). */ txns: NeftRtgsTxn[]; } @Component({ selector: 'mifosx-sender-history-dialog', templateUrl: './sender-history-dialog.component.html', styleUrls: ['./sender-history-dialog.component.scss'], imports: [ ...STANDALONE_SHARED_IMPORTS, CommonModule, FaIconComponent, MatTooltip ] }) export class SenderHistoryDialogComponent { private dialogRef = inject(MatDialogRef); data: SenderHistoryDialogData = inject(MAT_DIALOG_DATA); /** Today's date as YYYY-MM-DD — matches the `valueDate` shape in the txn seed. */ private get todayKey(): string { const d = new Date(); const pad = (n: number) => String(n).padStart(2, '0'); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; } /** * Today's NEFT/RTGS rows for this sender — matched by exact A/C number when * available, otherwise by case-insensitive holder name (since the demo seed * and operator account list don't share account numbers). Older value dates * are excluded; this view is intentionally a today-only snapshot. */ get filteredTxns(): NeftRtgsTxn[] { const acc = (this.data.senderAccountNo || '').trim().toLowerCase(); const name = (this.data.senderName || '').trim().toLowerCase(); const today = this.todayKey; return (this.data.txns || []).filter((t) => { if (t.valueDate !== today) return false; if (acc && t.remitterAcc.toLowerCase() === acc) return true; if (name && t.remitterUser.toLowerCase() === name) return true; return false; }); } // ─── KPI getters ─── get totalCount(): number { return this.filteredTxns.length; } get totalAmount(): number { return this.filteredTxns.reduce((s, t) => s + t.amount, 0); } get settledCount(): number { return this.filteredTxns.filter((t) => t.processingState === 'SETTLED').length; } get pendingCount(): number { return this.filteredTxns.filter((t) => [ 'UPLOADED', 'VALIDATED', 'SENT', 'PENDING' ].includes(t.processingState)).length; } get returnedCount(): number { return this.filteredTxns.filter((t) => t.processingState === 'RETURNED').length; } get successRate(): number { if (this.totalCount === 0) return 0; return (this.settledCount / this.totalCount) * 100; } 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'; } } close(): void { this.dialogRef.close(); } }