diff --git a/src/app/accounts/accounts.service.ts b/src/app/accounts/accounts.service.ts index fb262c0bc..ad7e49688 100644 --- a/src/app/accounts/accounts.service.ts +++ b/src/app/accounts/accounts.service.ts @@ -89,4 +89,8 @@ export class AccountsService { if (params.asOnDate) httpParams = httpParams.set('asOnDate', params.asOnDate); return this.http.get('/recurringdepositaccounts', { params: httpParams }); } + + terminateAccount(accountId: string, data: any): Observable { + return this.http.post(`/v1/accounts/${accountId}/terminate`, data); + } } diff --git a/src/app/current-accounts/current-account-view/current-account-view.component.ts b/src/app/current-accounts/current-account-view/current-account-view.component.ts index ed398d664..3129db777 100644 --- a/src/app/current-accounts/current-account-view/current-account-view.component.ts +++ b/src/app/current-accounts/current-account-view/current-account-view.component.ts @@ -24,6 +24,9 @@ import { ClientsService } from 'app/clients/clients.service'; import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component'; import { Currency } from 'app/shared/models/general.model'; import { TranslateService } from '@ngx-translate/core'; +import { AccountsService } from 'app/accounts/accounts.service'; +import { SettingsService } from 'app/settings/settings.service'; +import { Dates } from 'app/core/utils/dates'; /** Environment Configuration */ import { environment } from '../../../environments/environment'; @@ -83,6 +86,9 @@ export class CurrentAccountViewComponent implements OnInit { private currentAccountsService = inject(CurrentAccountsService); private clientsService = inject(ClientsService); private translateService = inject(TranslateService); + private accountsService = inject(AccountsService); + private settingsService = inject(SettingsService); + private dateUtils = inject(Dates); dialog = inject(MatDialog); /** Current Account Data */ @@ -126,7 +132,8 @@ export class CurrentAccountViewComponent implements OnInit { Close: 'danger', Reject: 'danger', Delete: 'danger', - 'Withdrawn by Client': 'danger' + 'Withdrawn by Client': 'danger', + Terminate: 'danger' }; private readonly ACTION_ICON: Record = { @@ -157,7 +164,8 @@ export class CurrentAccountViewComponent implements OnInit { Close: 'times-circle', Reject: 'ban', Delete: 'trash', - 'Withdrawn by Client': 'user-slash' + 'Withdrawn by Client': 'user-slash', + Terminate: 'times-circle' }; kindOf(name: string): 'transact' | 'block' | 'interest' | 'admin' | 'danger' { @@ -309,6 +317,9 @@ export class CurrentAccountViewComponent implements OnInit { case 'Delete': this.deleteCurrentAccount(); break; + case 'Terminate': + this.terminateCurrentAccount(); + break; case 'Calculate Interest': this.calculateInterest(); break; @@ -370,6 +381,32 @@ export class CurrentAccountViewComponent implements OnInit { }); } + private terminateCurrentAccount() { + const terminateCurrentAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + heading: 'Terminate Account', + dialogContext: 'Are you sure you want to terminate this account?', + type: 'Strong' + } + }); + terminateCurrentAccountDialogRef.afterClosed().subscribe((response: any) => { + if (response && response.confirm) { + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + const terminatedOnDate = this.dateUtils.formatDate(new Date(), dateFormat); + const data = { + accountType: 'CURRENT', + terminatedOnDate, + dateFormat, + locale + }; + this.accountsService.terminateAccount(this.currentAccountData.id, data).subscribe(() => { + this.reload(); + }); + } + }); + } + /** * Calculates current account's interest */ diff --git a/src/app/current-accounts/current-account-view/current-accounts-buttons.config.ts b/src/app/current-accounts/current-account-view/current-accounts-buttons.config.ts index 9c33daef1..e5fb4df88 100644 --- a/src/app/current-accounts/current-account-view/current-accounts-buttons.config.ts +++ b/src/app/current-accounts/current-account-view/current-accounts-buttons.config.ts @@ -194,6 +194,10 @@ export class CurrentAccountButtonsConfiguration { { name: 'Delete', taskPermissionName: 'DELETE_CURRENTACCOUNT' + }, + { + name: 'Terminate', + taskPermissionName: 'DELETE_CURRENTACCOUNT' } ]; break; diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts index 9365357c0..17faad6f1 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposit-account-view.component.ts @@ -11,8 +11,8 @@ import { Component, OnInit, inject } from '@angular/core'; import { ActivatedRoute, Router, RouterLinkActive, RouterLink, RouterOutlet } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; -/** Custom Dialogs */ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; +import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component'; import { CalculateInterestDialogComponent } from './custom-dialogs/calculate-interest-dialog/calculate-interest-dialog.component'; import { PostInterestDialogComponent } from './custom-dialogs/post-interest-dialog/post-interest-dialog.component'; import { ToggleWithholdTaxDialogComponent } from './custom-dialogs/toggle-withhold-tax-dialog/toggle-withhold-tax-dialog.component'; @@ -23,7 +23,10 @@ import { FixedDepositsButtonsConfiguration } from './fixed-deposits-buttons.conf /** Custom Services */ import { FixedDepositsService } from '../fixed-deposits.service'; import { SavingsService } from 'app/savings/savings.service'; +import { AccountsService } from 'app/accounts/accounts.service'; import { Currency } from 'app/shared/models/general.model'; +import { SettingsService } from 'app/settings/settings.service'; +import { Dates } from 'app/core/utils/dates'; import { MatTooltip } from '@angular/material/tooltip'; import { NgClass, CurrencyPipe } from '@angular/common'; import { AccountNumberComponent } from '../../../shared/account-number/account-number.component'; @@ -67,6 +70,9 @@ export class FixedDepositAccountViewComponent implements OnInit { private router = inject(Router); private fixedDepositsService = inject(FixedDepositsService); private savingsService = inject(SavingsService); + private accountsService = inject(AccountsService); + private settingsService = inject(SettingsService); + private dateUtils = inject(Dates); dialog = inject(MatDialog); /** Fixed Deposits Account Data */ @@ -99,7 +105,8 @@ export class FixedDepositAccountViewComponent implements OnInit { 'Apply Annual Fees': 'admin', Reject: 'danger', 'Withdrawn by Client': 'danger', - Delete: 'danger' + Delete: 'danger', + Terminate: 'danger' }; private readonly ACTION_ICON: Record = { @@ -121,7 +128,8 @@ export class FixedDepositAccountViewComponent implements OnInit { 'Apply Annual Fees': 'receipt', Reject: 'ban', 'Withdrawn by Client': 'user-slash', - Delete: 'trash' + Delete: 'trash', + Terminate: 'times-circle' }; kindOf(name: string): 'transact' | 'block' | 'interest' | 'admin' | 'danger' { @@ -237,6 +245,9 @@ export class FixedDepositAccountViewComponent implements OnInit { case 'Disable Withhold Tax': this.disableWithHoldTax(); break; + case 'Terminate': + this.terminateFixedDepositsAccount(); + break; } } @@ -256,6 +267,32 @@ export class FixedDepositAccountViewComponent implements OnInit { }); } + private terminateFixedDepositsAccount() { + const terminateFixedDepositAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + heading: 'Terminate Account', + dialogContext: 'Are you sure you want to terminate this account?', + type: 'Strong' + } + }); + terminateFixedDepositAccountDialogRef.afterClosed().subscribe((response: any) => { + if (response && response.confirm) { + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + const terminatedOnDate = this.dateUtils.formatDate(new Date(), dateFormat); + const data = { + accountType: 'FD', + terminatedOnDate, + dateFormat, + locale + }; + this.accountsService.terminateAccount(this.fixedDepositsAccountData.id, data).subscribe(() => { + this.reload(); + }); + } + }); + } + /** * Calculates fixed deposit account's interest */ diff --git a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposits-buttons.config.ts b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposits-buttons.config.ts index b4a2ea5e0..271987c9e 100644 --- a/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposits-buttons.config.ts +++ b/src/app/deposits/fixed-deposits/fixed-deposit-account-view/fixed-deposits-buttons.config.ts @@ -132,6 +132,9 @@ export class FixedDepositsButtonsConfiguration { }, { name: 'Delete' + }, + { + name: 'Terminate' } ]; break; diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts index d466d62bb..55c4deb69 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts @@ -20,9 +20,13 @@ import { RecurringDepositsButtonsConfiguration } from './recurring-deposits-butt /** Custom Dialogs */ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; +import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component'; import { RecurringDepositConfirmationDialogComponent } from './custom-dialogs/recurring-deposit-confirmation-dialog/recurring-deposit-confirmation-dialog.component'; import { Currency } from 'app/shared/models/general.model'; import { TranslateService } from '@ngx-translate/core'; +import { AccountsService } from 'app/accounts/accounts.service'; +import { SettingsService } from 'app/settings/settings.service'; +import { Dates } from 'app/core/utils/dates'; import { MatTooltip } from '@angular/material/tooltip'; import { NgClass, DecimalPipe, CurrencyPipe } from '@angular/common'; import { AccountNumberComponent } from '../../../shared/account-number/account-number.component'; @@ -67,6 +71,9 @@ export class RecurringDepositsAccountViewComponent implements OnInit { private router = inject(Router); private recurringDepositsService = inject(RecurringDepositsService); private savingsService = inject(SavingsService); + private accountsService = inject(AccountsService); + private settingsService = inject(SettingsService); + private dateUtils = inject(Dates); dialog = inject(MatDialog); private translateService = inject(TranslateService); @@ -103,7 +110,8 @@ export class RecurringDepositsAccountViewComponent implements OnInit { 'Apply Annual Fees': 'admin', Reject: 'danger', 'Withdrawn by Client': 'danger', - Delete: 'danger' + Delete: 'danger', + Terminate: 'danger' }; private readonly ACTION_ICON: Record = { @@ -125,7 +133,8 @@ export class RecurringDepositsAccountViewComponent implements OnInit { 'Apply Annual Fees': 'receipt', Reject: 'ban', 'Withdrawn by Client': 'user-slash', - Delete: 'trash' + Delete: 'trash', + Terminate: 'times-circle' }; kindOf(name: string): 'transact' | 'block' | 'interest' | 'admin' | 'danger' { @@ -287,6 +296,9 @@ export class RecurringDepositsAccountViewComponent implements OnInit { case 'Disable Withhold Tax': this.disableWithHoldTax(); break; + case 'Terminate': + this.terminateRecurringDepositsAccount(); + break; } } @@ -308,6 +320,32 @@ export class RecurringDepositsAccountViewComponent implements OnInit { }); } + private terminateRecurringDepositsAccount() { + const terminateRecurringDepositAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + heading: 'Terminate Account', + dialogContext: 'Are you sure you want to terminate this account?', + type: 'Strong' + } + }); + terminateRecurringDepositAccountDialogRef.afterClosed().subscribe((response: any) => { + if (response && response.confirm) { + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + const terminatedOnDate = this.dateUtils.formatDate(new Date(), dateFormat); + const data = { + accountType: 'RD', + terminatedOnDate, + dateFormat, + locale + }; + this.accountsService.terminateAccount(this.recurringDepositsAccountData.id, data).subscribe(() => { + this.reload(); + }); + } + }); + } + /** * Calculates savings account's interest */ diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-buttons.config.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-buttons.config.ts index 5c18484c6..7e2f5dd5f 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-buttons.config.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-buttons.config.ts @@ -163,6 +163,11 @@ export class RecurringDepositsButtonsConfiguration { name: 'Delete', icon: 'trash', taskPermissionName: 'DELETE_RECURRINGDEPOSITACCOUNT' + }, + { + name: 'Terminate', + icon: 'times-circle', + taskPermissionName: 'DELETE_RECURRINGDEPOSITACCOUNT' } ]; break; diff --git a/src/app/pipes/status-lookup.pipe.ts b/src/app/pipes/status-lookup.pipe.ts index 33845febd..291729023 100644 --- a/src/app/pipes/status-lookup.pipe.ts +++ b/src/app/pipes/status-lookup.pipe.ts @@ -30,6 +30,7 @@ export class StatusLookupPipe implements PipeTransform { 'savingsAccountStatusType.activeInactive': 'status-active-overdue', 'savingsAccountStatusType.activeDormant': 'status-active-overdue', 'savingsAccountStatusType.matured': 'status-matured', + 'savingsAccountStatusType.terminated': 'status-deleted', 'shareAccountStatusType.submitted.and.pending.approval': 'status-pending', 'shareAccountStatusType.approved': 'status-approved', 'shareAccountStatusType.active': 'status-active', diff --git a/src/app/savings/savings-account-view/savings-account-view.component.ts b/src/app/savings/savings-account-view/savings-account-view.component.ts index 8d1603aa0..ab5de3bf3 100644 --- a/src/app/savings/savings-account-view/savings-account-view.component.ts +++ b/src/app/savings/savings-account-view/savings-account-view.component.ts @@ -24,6 +24,9 @@ import { SavingsService } from '../savings.service'; import { ConfirmationDialogComponent } from 'app/shared/confirmation-dialog/confirmation-dialog.component'; import { Currency } from 'app/shared/models/general.model'; import { TranslateService } from '@ngx-translate/core'; +import { AccountsService } from 'app/accounts/accounts.service'; +import { SettingsService } from 'app/settings/settings.service'; +import { Dates } from 'app/core/utils/dates'; /** Environment Configuration */ import { environment } from '../../../environments/environment'; @@ -75,6 +78,9 @@ export class SavingsAccountViewComponent implements OnInit { private router = inject(Router); private savingsService = inject(SavingsService); private translateService = inject(TranslateService); + private accountsService = inject(AccountsService); + private settingsService = inject(SettingsService); + private dateUtils = inject(Dates); dialog = inject(MatDialog); /** Savings Account Data */ @@ -124,7 +130,8 @@ export class SavingsAccountViewComponent implements OnInit { Close: 'danger', Reject: 'danger', Delete: 'danger', - 'Withdrawn by Client': 'danger' + 'Withdrawn by Client': 'danger', + Terminate: 'danger' }; /** Lightweight icon fallback for actions whose buttonConfig doesn't @@ -157,7 +164,8 @@ export class SavingsAccountViewComponent implements OnInit { Close: 'times-circle', Reject: 'ban', Delete: 'trash', - 'Withdrawn by Client': 'user-slash' + 'Withdrawn by Client': 'user-slash', + Terminate: 'times-circle' }; /** Returns the colour kind for a given action name (used to tint the @@ -306,6 +314,9 @@ export class SavingsAccountViewComponent implements OnInit { case 'Delete': this.deleteSavingsAccount(); break; + case 'Terminate': + this.terminateSavingsAccount(); + break; case 'Calculate Interest': this.calculateInterest(); break; @@ -363,6 +374,35 @@ export class SavingsAccountViewComponent implements OnInit { }); } + /** + * Terminates Savings Account. + */ + private terminateSavingsAccount() { + const terminateSavingsAccountDialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + heading: 'Terminate Account', + dialogContext: 'Are you sure you want to terminate this account?', + type: 'Strong' + } + }); + terminateSavingsAccountDialogRef.afterClosed().subscribe((response: any) => { + if (response && response.confirm) { + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + const terminatedOnDate = this.dateUtils.formatDate(new Date(), dateFormat); + const data = { + accountType: 'SAVINGS', + terminatedOnDate, + dateFormat, + locale + }; + this.accountsService.terminateAccount(this.savingsAccountData.id, data).subscribe(() => { + this.reload(); + }); + } + }); + } + /** * Calculates savings account's interest */ diff --git a/src/app/savings/savings-account-view/savings-buttons.config.ts b/src/app/savings/savings-account-view/savings-buttons.config.ts index ffee9dea1..47198897f 100644 --- a/src/app/savings/savings-account-view/savings-buttons.config.ts +++ b/src/app/savings/savings-account-view/savings-buttons.config.ts @@ -192,6 +192,10 @@ export class SavingsButtonsConfiguration { { name: 'Delete', taskPermissionName: 'DELETE_SAVINGSACCOUNT' + }, + { + name: 'Terminate', + taskPermissionName: 'DELETE_SAVINGSACCOUNT' } ]; break; diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/checker-inbox/checker-inbox.component.ts b/src/app/tasks/checker-inbox-and-tasks-tabs/checker-inbox/checker-inbox.component.ts index dbf7036bb..237dbb2c0 100644 --- a/src/app/tasks/checker-inbox-and-tasks-tabs/checker-inbox/checker-inbox.component.ts +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/checker-inbox/checker-inbox.component.ts @@ -115,11 +115,10 @@ export class CheckerInboxComponent implements OnInit { */ constructor() { this.route.data.subscribe((data: { makerCheckerResource: any; makerCheckerTemplate: any }) => { - this.searchData = data.makerCheckerResource; - if (this.searchData.length > 0) { - this.checkerData = true; - } - this.makerCheckerTemplate = data.makerCheckerTemplate; + const raw = data.makerCheckerResource; + this.searchData = Array.isArray(raw) ? raw : (raw?.pageItems ?? []); + this.checkerData = this.searchData.length > 0; + this.makerCheckerTemplate = data.makerCheckerTemplate ?? {}; this.dataSource = new MatTableDataSource(this.searchData); this.selection = new SelectionModel(true, []); }); diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts index b607edd10..8fa43a3fe 100644 --- a/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/pending-account/pending-account.component.ts @@ -82,8 +82,10 @@ export class PendingAccountComponent { constructor() { this.route.data.subscribe((data: { pendingAccountsData: any }) => { - // status 100 = submitted and pending approval only; exclude active/approved/etc. - const items = (data.pendingAccountsData?.pageItems || []).filter((a: any) => a.status?.id === 100); + // status 100 = submitted and pending approval only; exclude terminated accounts + const items = (data.pendingAccountsData?.pageItems || []).filter( + (a: any) => a.status?.id === 100 && !a.terminateTrue + ); this.showData = items.length > 0; this.dataSource = new MatTableDataSource(items); this.selection = new SelectionModel(true, []); diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.html b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.html new file mode 100644 index 000000000..e9142a221 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.html @@ -0,0 +1,75 @@ + + +
+ @if (showData) { +
+ + search + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Account No{{ row.accountNo }}Client Name{{ row.clientName }}Product{{ row.savingsProductName || row.productName }}Type{{ row.accountType }}Office{{ row.officeName }}Submitted On{{ formatDate(row.timeline?.submittedOnDate || row.submittedOnDate) }}Status + Terminated +
+
+ } + + @if (!showData) { +
+ +

No terminated accounts

+

Accounts marked for termination will appear here.

+
+ } +
diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.scss b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.scss new file mode 100644 index 000000000..a573feda6 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.scss @@ -0,0 +1,17 @@ +/** + * 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/. + */ + +.status-badge--terminated { + background: #fef2f2; + color: #dc2626; + border: 1px solid #fecaca; + padding: 2px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: 500; +} diff --git a/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.ts b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.ts new file mode 100644 index 000000000..e74e61ec2 --- /dev/null +++ b/src/app/tasks/checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component.ts @@ -0,0 +1,106 @@ +/** + * 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 { ActivatedRoute, Router } from '@angular/router'; +import { + MatTableDataSource, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCellDef, + MatCell, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow +} from '@angular/material/table'; +import { MatIcon } from '@angular/material/icon'; +import { FaIconComponent } from '@fortawesome/angular-fontawesome'; +import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; + +@Component({ + selector: 'mifosx-terminated-account', + templateUrl: './terminated-account.component.html', + styleUrls: ['./terminated-account.component.scss'], + imports: [ + ...STANDALONE_SHARED_IMPORTS, + FaIconComponent, + MatTable, + MatColumnDef, + MatHeaderCellDef, + MatHeaderCell, + MatCellDef, + MatCell, + MatHeaderRowDef, + MatHeaderRow, + MatRowDef, + MatRow, + MatIcon + ] +}) +export class TerminatedAccountComponent { + private route = inject(ActivatedRoute); + private router = inject(Router); + + dataSource: MatTableDataSource; + showData = false; + + displayedColumns: string[] = [ + 'accountNo', + 'clientName', + 'productName', + 'accountType', + 'officeName', + 'submittedOnDate', + 'status' + ]; + + constructor() { + this.route.data.subscribe((data: { terminatedAccountsData: any }) => { + const items = data.terminatedAccountsData?.pageItems || []; + this.showData = items.length > 0; + this.dataSource = new MatTableDataSource(items); + }); + } + + navigateToAccount(account: any): void { + const clientId = account.clientId; + const accountId = account.id; + const depositTypeId = account.depositType?.id; + if (account.accountType === 'Current') { + this.router.navigate([`/clients/${clientId}/current-accounts/${accountId}`]); + } else if (depositTypeId === 200) { + this.router.navigate([`/clients/${clientId}/fixed-deposits-accounts/${accountId}`]); + } else if (depositTypeId === 300) { + this.router.navigate([`/clients/${clientId}/recurring-deposits-accounts/${accountId}`]); + } else { + this.router.navigate([`/clients/${clientId}/savings-accounts/${accountId}`]); + } + } + + applyFilter(filterValue: string = '') { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + formatDate(date: any): string { + if (!date) return ''; + if (Array.isArray(date)) { + return new Date(date[0], date[1] - 1, date[2]).toLocaleDateString('en-IN', { + day: '2-digit', + month: 'short', + year: 'numeric' + }); + } + const d = new Date(date); + return isNaN(d.getTime()) + ? date + : d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }); + } +} diff --git a/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html b/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html index 349c6cfed..34e31fe3d 100644 --- a/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html +++ b/src/app/tasks/checker-inbox-and-tasks/checker-inbox-and-tasks.component.html @@ -106,6 +106,18 @@ Reject Account + + + Terminated Account + { + private tasksService = inject(TasksService); + + resolve(): Observable { + return forkJoin({ + savings: this.tasksService.getTerminatedSavingsAccounts().pipe(catchError(() => of({ pageItems: [] }))), + current: this.tasksService.getTerminatedCurrentAccounts().pipe(catchError(() => of([]))), + offices: this.tasksService.getAllOffices().pipe(catchError(() => of([]))) + }).pipe( + map((results) => { + const officeMap: Record = {}; + (results.offices || []).forEach((o: any) => { + officeMap[o.id] = o.name; + }); + + const savingsItems = (results.savings?.pageItems || []).map((a: any) => ({ + ...a, + officeName: officeMap[a.officeId] || a.officeName || '', + fieldOfficerName: a.fieldOfficerName || '', + accountType: a.depositType?.value || 'Savings' + })); + + const currentItems = (Array.isArray(results.current) ? results.current : results.current?.pageItems || []).map( + (a: any) => ({ ...a, accountType: 'Current' }) + ); + + return { pageItems: [ + ...savingsItems, + ...currentItems + ] }; + }) + ); + } +} diff --git a/src/app/tasks/tasks-routing.module.ts b/src/app/tasks/tasks-routing.module.ts index 573faee07..39f0940a1 100644 --- a/src/app/tasks/tasks-routing.module.ts +++ b/src/app/tasks/tasks-routing.module.ts @@ -25,6 +25,7 @@ import { LoanDisbursalComponent } from './checker-inbox-and-tasks-tabs/loan-disb import { RescheduleLoanComponent } from './checker-inbox-and-tasks-tabs/reschedule-loan/reschedule-loan.component'; import { PendingAccountComponent } from './checker-inbox-and-tasks-tabs/pending-account/pending-account.component'; import { RejectedAccountComponent } from './checker-inbox-and-tasks-tabs/rejected-account/rejected-account.component'; +import { TerminatedAccountComponent } from './checker-inbox-and-tasks-tabs/terminated-account/terminated-account.component'; import { ViewCheckerInboxComponent } from './view-checker-inbox/view-checker-inbox.component'; /** Custom Resolvers */ @@ -38,6 +39,7 @@ import { MakerCheckerTemplate } from './common-resolvers/makerCheckerTemplate.re import { GetCheckerInboxDetailResolver } from './common-resolvers/getCheckerInboxDetail.resolver'; import { GetPendingAccounts } from './common-resolvers/getPendingAccounts.resolver'; import { GetRejectedAccounts } from './common-resolvers/getRejectedAccounts.resolver'; +import { GetTerminatedAccounts } from './common-resolvers/getTerminatedAccounts.resolver'; /** Tasks Routes */ const routes: Routes = [ @@ -105,6 +107,14 @@ const routes: Routes = [ rejectedAccountsData: GetRejectedAccounts } }, + { + path: 'terminated-account', + component: TerminatedAccountComponent, + data: { title: 'Terminated Account' }, + resolve: { + terminatedAccountsData: GetTerminatedAccounts + } + }, { path: 'withdrawal-requests', component: WithdrawalRequestsComponent, @@ -175,7 +185,8 @@ const routes: Routes = [ MakerCheckerTemplate, GetCheckerInboxDetailResolver, GetPendingAccounts, - GetRejectedAccounts + GetRejectedAccounts, + GetTerminatedAccounts ] }) export class TasksRoutingModule {} diff --git a/src/app/tasks/tasks.service.ts b/src/app/tasks/tasks.service.ts index 23587339a..294ce91de 100644 --- a/src/app/tasks/tasks.service.ts +++ b/src/app/tasks/tasks.service.ts @@ -140,6 +140,16 @@ export class TasksService { return this.http.get('/currentaccounts', { params: httpParams }); } + getTerminatedSavingsAccounts(): Observable { + const httpParams = new HttpParams().set('limit', '1000').set('status', 'terminated'); + return this.http.get('/savingsaccounts', { params: httpParams }); + } + + getTerminatedCurrentAccounts(): Observable { + const httpParams = new HttpParams().set('limit', '1000').set('status', 'terminated'); + return this.http.get('/currentaccounts', { params: httpParams }); + } + /** * Approve a savings account */