Files
cbsnexora/src/app/savings/savings-account-stepper/savings-account-preview-step/savings-account-preview-step.component.ts
T
AdityaandClaude Opus 4.7 b149fef72e feat: KYC re-verify UX, family/nominee tab gating, savings dialogs, cfcfrms shell
- KYC tab: fix Verify (PAN) and Send OTP (Aadhaar) being disabled in edit mode;
  unmask Aadhaar input and show on-file masked value as hint; resolve kycId
  from id/kycId/resourceId fallbacks.
- Client stepper/view: add familyAllowed / nomineeAllowed predicates +
  CanActivate route guards. Family tab hidden for non-individuals, Nominee
  tab hidden for non-proprietor entities. Family-members step accepts a
  nomineeOnly input for proprietorship clients. Add/Edit/Delete buttons
  inside family-members and nominee tabs gated by canAdd.
- cfcfrms: add cfcfrms-shell wrapper, restyle complaint/fraud/mule/escalate
  pages and dashboard.
- Savings: identity-verify and transaction-confirm dialogs, manage / activate
  / add-charge flows, account preview styling.
- Tasks, core shell, account-nominees, icons: minor style and behaviour
  updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:49:43 +05:30

153 lines
4.8 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/.
*/
/** Angular Imports */
import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import {
MatTableDataSource,
MatTable,
MatColumnDef,
MatHeaderCellDef,
MatHeaderCell,
MatCellDef,
MatCell,
MatHeaderRowDef,
MatHeaderRow,
MatRowDef,
MatRow
} from '@angular/material/table';
import { MatDivider } from '@angular/material/divider';
import { ExternalIdentifierComponent } from '../../../shared/external-identifier/external-identifier.component';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { FindPipe } from '../../../pipes/find.pipe';
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
import { FormatNumberPipe } from '../../../pipes/format-number.pipe';
import { YesnoPipe } from '../../../pipes/yesno.pipe';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
* Savings account preview step
*/
@Component({
selector: 'mifosx-savings-account-preview-step',
templateUrl: './savings-account-preview-step.component.html',
styleUrls: ['./savings-account-preview-step.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS,
MatDivider,
ExternalIdentifierComponent,
MatTable,
MatColumnDef,
MatHeaderCellDef,
MatHeaderCell,
MatCellDef,
MatCell,
MatHeaderRowDef,
MatHeaderRow,
MatRowDef,
MatRow,
FaIconComponent,
FindPipe,
DateFormatPipe,
FormatNumberPipe,
YesnoPipe
]
})
export class SavingsAccountPreviewStepComponent implements OnChanges {
readonly digitalFacilityLabels = [
{ key: 'atmFacility', label: 'ATM Facility' },
{ key: 'atmWithdrawalFacility', label: 'ATM Withdrawal' },
{ key: 'upiFacility', label: 'UPI Facility' },
{ key: 'posTransactionsFacility', label: 'POS Transactions' },
{ key: 'chequeBook', label: 'Cheque Book' },
{ key: 'impsFacility', label: 'IMPS Facility' },
{ key: 'smsAlerts', label: 'SMS Alerts' },
{ key: 'bbpsFacility', label: 'BBPS Facility' },
{ key: 'insuranceCover', label: 'Insurance Cover' },
{ key: 'bepgFacility', label: 'BEPG Facility' },
{ key: 'neftFacility', label: 'NEFT Facility' },
{ key: 'rtgsFacility', label: 'RTGS Facility' },
{ key: 'interBankTotalCapFacility', label: 'Inter-Bank Total Cap' },
{ key: 'withdrawalFacility', label: 'Withdrawal Facility' },
{ key: 'depositFacilityKyc', label: 'Deposit Facility (KYC)' },
{ key: 'virtualDebitCard', label: 'Virtual Debit Card' }
];
/** Savings Account Product Template */
@Input() savingsAccountProductTemplate: any;
/** Savings Account Template */
@Input() savingsAccountTemplate: any;
/** Savings Account Terms Form */
@Input() savingsAccountTermsForm: any;
/** Savings Account */
@Input() savingsAccount: any;
/** Digital facilities — user-modified values from digital step */
@Input() savingsAccountDigital: any;
/** Nominees list from currency step */
@Input() savingsAccountNominees: any[] = [];
/** active Client Members in case of GSIM Account */
@Input() activeClientMembers?: any;
/** Table Data Source */
dataSource: any;
/** Display columns for charges table */
chargesDisplayedColumns: string[] = [
'name',
'chargeCalculationType',
'amount',
'chargeTimeType',
'date',
'repaymentsEvery'
];
/** Columns to be displayed in active members table. */
membersDisplayedColumns: string[] = [
'id',
'name'
];
/** Form submission event */
@Output() submitEvent = new EventEmitter();
ngOnChanges(): void {
if (this.activeClientMembers?.length > 0) {
this.dataSource = new MatTableDataSource<any>(this.activeClientMembers.filter((member: any) => member.selected));
}
}
/** Returns user-modified digital config (from digital step), falling back to product template */
get digitalFacilityConfig(): any {
return (
this.savingsAccountDigital?.accountFacilityConfig ??
this.savingsAccountProductTemplate?.accountFacilityConfig ??
null
);
}
get hasDigitalSection(): boolean {
return !!this.digitalFacilityConfig;
}
/** Currency info from product template */
get currencyName(): string {
return (
this.savingsAccountProductTemplate?.currency?.name ||
this.savingsAccountTermsForm?.get?.('currencyCode')?.value ||
'—'
);
}
get decimalPlaces(): string | number {
return this.savingsAccountProductTemplate?.currency?.decimalPlaces ?? '—';
}
get inMultiplesOf(): string | number {
return this.savingsAccountProductTemplate?.currency?.inMultiplesOf ?? '—';
}
}