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:
co-authored by
Claude Opus 4.6
parent
73aa69ee02
commit
0a32d7135e
+101
@@ -0,0 +1,101 @@
|
||||
<!--
|
||||
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="tab-container mat-typography">
|
||||
<div class="m-b-10">
|
||||
<h3>{{ 'labels.heading.All Standing Instructions' | translate }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z1 m-b-25">
|
||||
<table mat-table #instructionsTable [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="client">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Client' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
{{ instruction.fromClient.displayName }}-{{ instruction.fromClient.id }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fromAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.From Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
{{ instruction.fromAccount.accountNo }} ({{ instruction.fromAccountType.value }})
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="beneficiary">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Beneficiary' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">{{ instruction.toClient.displayName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="toAccount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.To Account' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
{{ instruction.toAccount.accountNo }} ({{ instruction.toAccountType.value }})
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Amount' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">{{ instruction.instructionType.value }}/{{ instruction.amount }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="validity">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Validity' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
{{ instruction.validFrom | dateFormat }} {{ 'labels.inputs.To' | translate }}
|
||||
{{ instruction.validTill | dateFormat }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'labels.inputs.Actions' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let instruction">
|
||||
@if (instruction.status.value !== 'Deleted') {
|
||||
<span>
|
||||
<button
|
||||
class="account-action-button"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
matTooltip="{{ 'tooltips.Edit Standing Instruction' | translate }}"
|
||||
*mifosxHasPermission="'UPDATE_STANDINGINSTRUCTION'"
|
||||
>
|
||||
<i class="fa fa-edit"></i>
|
||||
</button>
|
||||
</span>
|
||||
}
|
||||
@if (instruction.status.value !== 'Deleted') {
|
||||
<span>
|
||||
<button
|
||||
class="account-action-button"
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
matTooltip="{{ 'tooltips.Delete Standing Instruction' | translate }}"
|
||||
*mifosxHasPermission="'DELETE_STANDINGINSTRUCTION'"
|
||||
(click)="deleteStandingInstruction(instruction.id)"
|
||||
>
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
</span>
|
||||
}
|
||||
<button
|
||||
class="account-action-button"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
matTooltip="{{ 'tooltips.View Standing Instruction' | translate }}"
|
||||
*mifosxHasPermission="'READ_STANDINGINSTRUCTION'"
|
||||
>
|
||||
<i class="fa fa-eye"></i>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
+31
@@ -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/.
|
||||
*/
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
|
||||
h3 {
|
||||
margin: 1% auto;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
.account-action-button {
|
||||
min-width: 26px;
|
||||
padding: 0 6px;
|
||||
margin: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* 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, ViewChild, inject } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {
|
||||
MatTableDataSource,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderCell,
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow
|
||||
} from '@angular/material/table';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
/** Custom Services */
|
||||
import { CurrentAccountsService } from 'app/current-accounts/current-accounts.service';
|
||||
import { AccountTransfersService } from 'app/account-transfers/account-transfers.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
/** Dialog Components */
|
||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { DateFormatPipe } from '../../../pipes/date-format.pipe';
|
||||
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
||||
|
||||
/**
|
||||
* Current Account Standing Instructions Tab
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-standing-instructions-tab',
|
||||
templateUrl: './standing-instructions-tab.component.html',
|
||||
styleUrls: ['./standing-instructions-tab.component.scss'],
|
||||
imports: [
|
||||
...STANDALONE_SHARED_IMPORTS,
|
||||
MatTable,
|
||||
MatColumnDef,
|
||||
MatHeaderCellDef,
|
||||
MatHeaderCell,
|
||||
MatCellDef,
|
||||
MatCell,
|
||||
MatTooltip,
|
||||
MatHeaderRowDef,
|
||||
MatHeaderRow,
|
||||
MatRowDef,
|
||||
MatRow,
|
||||
DateFormatPipe
|
||||
]
|
||||
})
|
||||
export class StandingInstructionsTabComponent implements OnInit {
|
||||
private route = inject(ActivatedRoute);
|
||||
private currentAccountsService = inject(CurrentAccountsService);
|
||||
private dialog = inject(MatDialog);
|
||||
private accountTransfersService = inject(AccountTransfersService);
|
||||
private settingsService = inject(SettingsService);
|
||||
|
||||
/** Current Account Data */
|
||||
currentAccountData: any;
|
||||
/** Instructions Data */
|
||||
instructionsData: any[];
|
||||
/** Data source for instructions table. */
|
||||
dataSource = new MatTableDataSource();
|
||||
/** Columns to be displayed in instructions table. */
|
||||
displayedColumns: string[] = [
|
||||
'client',
|
||||
'fromAccount',
|
||||
'beneficiary',
|
||||
'toAccount',
|
||||
'amount',
|
||||
'validity',
|
||||
'actions'
|
||||
];
|
||||
|
||||
/** Instruction Table Reference */
|
||||
@ViewChild('instructionsTable', { static: true }) instructionTableRef: MatTable<Element>;
|
||||
|
||||
/**
|
||||
* Retrieves Current Account Data from `resolve`.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* @param {SettingsService} settingsService Setting service
|
||||
*/
|
||||
constructor() {
|
||||
this.route.parent.data.subscribe((data: { currentAccountData: any }) => {
|
||||
this.currentAccountData = data.currentAccountData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.getStandingInstructions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves standing instructions and initializes instructions table.
|
||||
*/
|
||||
getStandingInstructions() {
|
||||
const clientId = this.currentAccountData.clientId;
|
||||
const clientName = this.currentAccountData.clientName;
|
||||
const accountId = this.currentAccountData.id;
|
||||
const locale = this.settingsService.language.code;
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
this.currentAccountsService
|
||||
.getStandingInstructions(clientId, clientName, accountId, locale, dateFormat)
|
||||
.subscribe((response: any) => {
|
||||
this.instructionsData = response.pageItems;
|
||||
this.dataSource.data = this.instructionsData;
|
||||
this.instructionTableRef.renderRows();
|
||||
});
|
||||
}
|
||||
|
||||
deleteStandingInstruction(instructionId: any) {
|
||||
const deleteStandingInstructionDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `standing instruction id: ${instructionId}` }
|
||||
});
|
||||
deleteStandingInstructionDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
this.accountTransfersService.deleteStandingInstrucions(instructionId).subscribe(() => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user