feat: add Current Account module, DIP verification, charges integration, and translations

- Current Account module with full CRUD, transactions, charges, hold/release, block/unblock
- Current Products management under Products module
- DIP mobile number verification with real API call to /lookup/check
- Sanctions verification dialog
- Charges support for Current Account (chargeAppliesTo=5) in create/edit
- Fixed permissions from SAVINGSACCOUNT to CURRENTACCOUNT across all current account components
- Added all missing translation keys for Current Account in en-US.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-17 18:23:37 +05:30
co-authored by Claude Opus 4.6
parent 73aa69ee02
commit 0a32d7135e
210 changed files with 15048 additions and 155 deletions
@@ -0,0 +1,78 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable, forkJoin, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
import { ClientsService } from 'app/clients/clients.service';
import { GroupsService } from 'app/groups/groups.service';
import { OrganizationService } from 'app/organization/organization.service';
/**
* Current Account Actions data resolver.
*/
@Injectable()
export class CurrentAccountActionsResolver {
private currentAccountsService = inject(CurrentAccountsService);
private clientsService = inject(ClientsService);
private groupsService = inject(GroupsService);
private organizationService = inject(OrganizationService);
/**
* Returns the Current account actions data.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const actionName = route.paramMap.get('name');
const currentAccountId =
route.paramMap.get('currentAccountId') || route.parent.parent.paramMap.get('currentAccountId');
switch (actionName) {
case 'Assign Staff':
return this.currentAccountsService.getCurrentAccountData(currentAccountId).pipe(
switchMap((account: any) => {
if (!account.clientId && !account.groupId) {
return of({ ...account, fieldOfficerOptions: [] });
}
const entityObs = account.clientId
? this.clientsService.getClientData(account.clientId)
: this.groupsService.getGroupData(account.groupId);
return entityObs.pipe(
switchMap((entity: any) => this.organizationService.getStaff(entity.officeId, true)),
map((staff: any) => ({
...account,
fieldOfficerOptions: staff
}))
);
})
);
case 'Add Charge':
return this.currentAccountsService.getCurrentAccountChargeTemplateResource(currentAccountId);
case 'Withdrawal':
case 'Deposit':
case 'Hold Amount':
return this.currentAccountsService.getCurrentAccountTransactionTemplateResource(currentAccountId);
case 'Close':
return forkJoin([
this.currentAccountsService.getCurrentAccountTransactionTemplateResource(currentAccountId),
this.currentAccountsService.getCurrentAccountData(currentAccountId)
]);
case 'Apply Annual Fees':
return this.currentAccountsService.getCurrentAccountData(currentAccountId);
default:
return undefined;
}
}
}
@@ -0,0 +1,35 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account data and template resolver.
*/
@Injectable()
export class CurrentAccountAndTemplateResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account data and template.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.paramMap.get('currentAccountId');
return this.currentAccountsService.getCurrentAccountAndTemplate(currentAccountId, true);
}
}
@@ -0,0 +1,36 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account Charge data resolver.
*/
@Injectable()
export class CurrentAccountChargeResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account Charge data.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.parent.paramMap.get('currentAccountId');
const chargeId = route.paramMap.get('id');
return this.currentAccountsService.getCurrentAccountCharge(currentAccountId, chargeId);
}
}
@@ -0,0 +1,36 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account Template resolver.
*/
@Injectable()
export class CurrentAccountTemplateResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Shares Account Template.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const entityId = route.paramMap.get('clientId') || route.paramMap.get('groupId') || route.paramMap.get('centerId');
const isGroup = route.paramMap.get('groupId') || route.paramMap.get('centerId') ? true : false;
return this.currentAccountsService.getCurrentAccountTemplate(entityId, undefined, isGroup);
}
}
@@ -0,0 +1,36 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account Transaction Template data resolver.
*/
@Injectable()
export class CurrentAccountTransactionTemplateResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account Transaction Template data.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.parent.paramMap.get('currentAccountId');
const transactionId = route.paramMap.get('id');
return this.currentAccountsService.getCurrentAccountTransactionTemplate(currentAccountId, transactionId);
}
}
@@ -0,0 +1,36 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account Transaction data resolver.
*/
@Injectable()
export class CurrentAccountTransactionResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account Transaction data.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.parent.paramMap.get('currentAccountId');
const transactionId = route.parent.paramMap.get('id');
return this.currentAccountsService.getCurrentAccountTransaction(currentAccountId, transactionId);
}
}
@@ -0,0 +1,35 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account data resolver.
*/
@Injectable()
export class CurrentAccountViewResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account data.
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.paramMap.get('currentAccountId');
return this.currentAccountsService.getCurrentAccountData(currentAccountId);
}
}
@@ -0,0 +1,38 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Account Datatable data resolver.
*/
@Injectable()
export class CurrentAccountDatatableResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account's Datatable data.
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const accountId =
route.parent.parent.paramMap.get('currentAccountId') ||
route.parent.parent.paramMap.get('fixedDepositAccountId') ||
route.parent.parent.paramMap.get('recurringDepositAccountId');
const datatableName = route.paramMap.get('datatableName');
return this.currentAccountsService.getCurrentAccountDatatable(accountId, datatableName);
}
}
@@ -0,0 +1,33 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { CurrentAccountsService } from '../current-accounts.service';
/**
* Current Accounts Datatables data resolver.
*/
@Injectable()
export class CurrentAccountDatatablesResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account's Datatables data.
* @returns {Observable<any>}
*/
resolve(): Observable<any> {
return this.currentAccountsService.getCurrentAccountDatatables();
}
}
@@ -0,0 +1,28 @@
/**
* 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 { ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { CurrentAccountsService } from '../current-accounts.service';
@Injectable({
providedIn: 'root'
})
export class CurrentAccountDocumentsResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account data.
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.parent.paramMap.get('currentAccountId');
return this.currentAccountsService.getCurrentAccountDocuments(currentAccountId);
}
}
@@ -0,0 +1,28 @@
/**
* 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 { ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { CurrentAccountsService } from '../current-accounts.service';
@Injectable({
providedIn: 'root'
})
export class CurrentAccountNotesResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Current Account data.
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const currentAccountId = route.parent.paramMap.get('currentAccountId');
return this.currentAccountsService.getCurrentAccountNotes(currentAccountId);
}
}
@@ -0,0 +1,47 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
import { ReportsService } from 'app/reports/reports.service';
import { SettingsService } from 'app/settings/settings.service';
/**
* Current Account Transaction Reciept resolver.
*/
@Injectable()
export class CurrentAccountTransactionRecieptResolver {
private reportsService = inject(ReportsService);
private settingsService = inject(SettingsService);
/**
* Returns the Current Account Transaction Reciept
* @param {ActivatedRouteSnapshot} route Route Snapshot
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const transactionId = route.paramMap.get('id');
const data = {
'output-type': 'PDF',
R_transactionId: transactionId
};
return this.reportsService.getPentahoRunReportData(
'Current Account Transaction Receipt',
data,
'default',
this.settingsService.language.code,
this.settingsService.dateFormat
);
}
}
@@ -0,0 +1,33 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
// rxjs Imports
import { Observable } from 'rxjs';
// Custom Service
import { CurrentAccountsService } from '../current-accounts.service';
@Injectable()
export class TransactionDatatableResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
* Returns the Transactions Account's Datatable data.
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const accountId = route.parent.parent.paramMap.get('id');
const datatableName = route.paramMap.get('datatableName');
return this.currentAccountsService.getCurrentAccountTransactionDatatable(accountId, datatableName);
}
}
@@ -0,0 +1,31 @@
/**
* 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 { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
// rxjs Imports
import { Observable } from 'rxjs';
// Custom Service
import { CurrentAccountsService } from '../current-accounts.service';
@Injectable()
export class TransactionDatatablesResolver {
private currentAccountsService = inject(CurrentAccountsService);
/**
*
* @param route
* @returns {Observable<any>}
*/
resolve(route: ActivatedRouteSnapshot): Observable<any> {
return this.currentAccountsService.getCurrentAccountTransactionDatatables();
}
}