feat: add Pending Account and Reject Account tabs to Approval Center

- Added Pending Account tab showing savings/FD/RD/current accounts with status=pending (100)
- Added Reject Account tab showing accounts with status=rejected (500)
- Each tab displays: account no, client name, product, type badge, office, field officer, submitted/rejected date, status
- Bulk approve with correct endpoint per deposit type (savings/FD/RD/current)
- Resolvers use forkJoin to fetch savings + current accounts in parallel
- Office name resolved via /offices map; field officer name taken directly from API response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-05-22 14:02:40 +05:30
co-authored by Claude Sonnet 4.6
parent 3370a95235
commit df96be9a0e
11 changed files with 1009 additions and 1 deletions
@@ -0,0 +1,49 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { Resolve } from '@angular/router';
import { Observable, forkJoin, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { TasksService } from '../tasks.service';
@Injectable()
export class GetPendingAccounts implements Resolve<any> {
private tasksService = inject(TasksService);
resolve(): Observable<any> {
return forkJoin({
savings: this.tasksService.getPendingSavingsAccounts().pipe(catchError(() => of({ pageItems: [] }))),
current: this.tasksService.getPendingCurrentAccounts().pipe(catchError(() => of([]))),
offices: this.tasksService.getAllOffices().pipe(catchError(() => of([])))
}).pipe(
map((results) => {
const officeMap: Record<number, string> = {};
(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
] };
})
);
}
}
@@ -0,0 +1,51 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { Resolve } from '@angular/router';
import { Observable, forkJoin, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { TasksService } from '../tasks.service';
@Injectable()
export class GetRejectedAccounts implements Resolve<any> {
private tasksService = inject(TasksService);
resolve(): Observable<any> {
return forkJoin({
savings: this.tasksService.getRejectedSavingsAccounts().pipe(catchError(() => of({ pageItems: [] }))),
current: this.tasksService.getRejectedCurrentAccounts().pipe(catchError(() => of([]))),
offices: this.tasksService.getAllOffices().pipe(catchError(() => of([])))
}).pipe(
map((results) => {
const officeMap: Record<number, string> = {};
(results.offices || []).forEach((o: any) => {
officeMap[o.id] = o.name;
});
const savingsItems = (results.savings?.pageItems || [])
.filter((a: any) => a.status?.id === 500)
.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 || [])
.filter((a: any) => a.status?.id === 500)
.map((a: any) => ({ ...a, accountType: 'Current' }));
return { pageItems: [
...savingsItems,
...currentItems
] };
})
);
}
}