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,44 @@
<!--
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/.
-->
<div class="container mat-elevation-z8">
<mat-card>
<form [formGroup]="currentAccountUnassignStaffForm" (ngSubmit)="submit()">
<mat-card-content>
<mat-form-field class="flex-fill" (click)="unassignedDatePicker.open()">
<mat-label>{{ 'labels.inputs.Unassignment Date' | translate }}</mat-label>
<input
matInput
[min]="minDate"
[max]="maxDate"
[matDatepicker]="unassignedDatePicker"
required
formControlName="unassignedDate"
/>
<mat-datepicker-toggle matSuffix [for]="unassignedDatePicker"></mat-datepicker-toggle>
<mat-datepicker #unassignedDatePicker></mat-datepicker>
@if (currentAccountUnassignStaffForm.controls.unassignedDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Unassignment Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
</mat-card-content>
<mat-card-actions class="layout-row align-center gap-5px responsive-column">
<button type="button" mat-raised-button [routerLink]="['../../']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-raised-button color="primary" [disabled]="!currentAccountUnassignStaffForm.valid">
{{ 'labels.buttons.Confirm' | translate }}
</button>
</mat-card-actions>
</form>
</mat-card>
</div>
@@ -0,0 +1,11 @@
/**
* 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/.
*/
.container {
max-width: 37rem;
}
@@ -0,0 +1,103 @@
/**
* 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, OnInit, Input, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { Dates } from 'app/core/utils/dates';
/** Custom Services */
import { CurrentAccountsService } from 'app/current-accounts/current-accounts.service';
import { SettingsService } from 'app/settings/settings.service';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
* Current Account Unassign Staff Component
*/
@Component({
selector: 'mifosx-current-account-account-unassign-staff',
templateUrl: './current-account-unassign-staff.component.html',
styleUrls: ['./current-account-unassign-staff.component.scss'],
imports: [
...STANDALONE_SHARED_IMPORTS
]
})
export class CurrentAccountUnassignStaffComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private currentAccountsService = inject(CurrentAccountsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
private settingsService = inject(SettingsService);
/** Minimum date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum date allowed. */
maxDate = new Date();
/** Current Account Unassign Staff form. */
currentAccountUnassignStaffForm: UntypedFormGroup;
/** Current Account Id */
accountId: any;
/**
* @param {FormBuilder} formBuilder Form Builder
* @param {CurrentAccountsService} currentAccountsService Current Accounts Service
* @param {Dates} dateUtils Date Utils
* @param {ActivatedRoute} route Activated Route
* @param {Router} router Router
* @param {SettingsService} settingsService Setting service
*/
constructor() {
this.accountId = this.route.snapshot.params['currentAccountId'];
}
/**
* Creates the current account unassign staff form.
*/
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
this.createCurrentAccountUnassignStaffForm();
}
/**
* Creates the current account unassign staff form.
*/
createCurrentAccountUnassignStaffForm() {
this.currentAccountUnassignStaffForm = this.formBuilder.group({
unassignedDate: [
'',
Validators.required
]
});
}
/**
* Submits the form and unassigns staff of the current account,
* if successful redirects to the current account.
*/
submit() {
const currentAccountUnassignStaffFormData = this.currentAccountUnassignStaffForm.value;
const locale = this.settingsService.language.code;
const dateFormat = this.settingsService.dateFormat;
const prevUnassignmentDate: Date = this.currentAccountUnassignStaffForm.value.unassignedDate;
if (currentAccountUnassignStaffFormData.unassignedDate instanceof Date) {
currentAccountUnassignStaffFormData.unassignedDate = this.dateUtils.formatDate(prevUnassignmentDate, dateFormat);
}
const data = {
...currentAccountUnassignStaffFormData,
dateFormat,
locale
};
this.currentAccountsService
.executeCurrentAccountCommand(this.accountId, 'unassignCurrentAccountOfficer', data)
.subscribe(() => {
this.router.navigate(['../../transactions'], { relativeTo: this.route });
});
}
}