feat(accounts): add Modify Application for rejected Current/Savings/FD/RD accounts

- Add 'Modify Application' button in kebab menu for rejected accounts (all 4 types)
- Rewrite edit components with tab-based UI matching create form
- Pre-populate all create-time values in edit form: product, account status,
  customer segment, account type, joint holders, nominees, introducer,
  deposit account link, senior citizen rate, tenure, flags (msme/balanceSwap/autoDebit)
- Fix edit mode detection using accountNo presence
- Add preselectedIntroducer @Input to IntroducerSearchComponent for pre-fill
- Support both camelCase and lowercase keys for joint holders (MySQL queryForList)
- Fix account number display: actual accountNo before previewAccountNo
- Fix cbsAccountType restore: cbsAccountType only, avoid Fineract enum object
- Add nominees fetch via /clients/{id}/nominees API in all 4 edit components
- Fix RD/FD Interest Rate Chart: SimpleChanges to prevent reset race condition
- Pre-check Senior Citizen checkbox in edit form from isSeniorCitizen DB field
- Auto-calculate rate when tenure pre-filled in edit mode
- FD calculator: use backend calculate-fd-interest API for all compounding types
- Support interestCompoundingPeriodInMonths=0 (daily) in FD calculator API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-06-03 10:36:40 +05:30
co-authored by Claude Sonnet 4.6
parent 3be2f96210
commit 260fabaa48
37 changed files with 2744 additions and 730 deletions
@@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { Component, Input, Output, EventEmitter, inject } from '@angular/core';
import { Component, Input, Output, EventEmitter, inject, OnChanges, SimpleChanges } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ClientsService } from 'app/clients/clients.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -27,11 +27,12 @@ import { FormsModule } from '@angular/forms';
MatIcon
]
})
export class IntroducerSearchComponent {
export class IntroducerSearchComponent implements OnChanges {
private clientsService = inject(ClientsService);
private sanitizer = inject(DomSanitizer);
@Input() excludedClientIds: number[] = [];
@Input() preselectedIntroducer: { clientId: number; displayName: string; cifNumber?: string } | null = null;
@Output() introducerChange = new EventEmitter<{ clientId: number; displayName: string; cifNumber?: string } | null>();
entryMode: 'linked' = 'linked';
@@ -50,6 +51,14 @@ export class IntroducerSearchComponent {
private searchTimer: any;
ngOnChanges(changes: SimpleChanges): void {
if (changes['preselectedIntroducer']?.currentValue && !this.selectedClient) {
const val = changes['preselectedIntroducer'].currentValue;
this.selectedClient = { id: val.clientId, displayName: val.displayName, cifNumber: val.cifNumber ?? '' };
this.fetchLinkedClientData(String(val.clientId));
}
}
onSearch(text: string): void {
this.searchText = text;
clearTimeout(this.searchTimer);