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
@@ -0,0 +1,367 @@
|
||||
<!--
|
||||
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/.
|
||||
-->
|
||||
|
||||
@if (isLoading) {
|
||||
<div class="loader">
|
||||
<div class="loading"></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!isLoading) {
|
||||
<div class="current-account-tables layout-row gap-2percent">
|
||||
<div class="flex-49 layout-column gap-4percent">
|
||||
@if (!currentAccountData.status.rejected && !currentAccountData.status.submittedAndPendingApproval) {
|
||||
<div>
|
||||
<h4 class="table-headers">{{ 'labels.heading.Current Account Details' | translate }}</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.External Id' | translate }}</td>
|
||||
@if (currentAccountData.externalId) {
|
||||
<td>
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ currentAccountData.externalId }}"
|
||||
></mifosx-external-identifier>
|
||||
</td>
|
||||
}
|
||||
@if (!currentAccountData.externalId) {
|
||||
<td>{{ 'labels.inputs.Not Provided' | translate }}</td>
|
||||
}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Activated On' | translate }}</td>
|
||||
<td>
|
||||
{{
|
||||
currentAccountData.timeline.activatedOnDate
|
||||
? (currentAccountData.timeline.activatedOnDate | dateFormat)
|
||||
: 'Not Activated'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Field Officer' | translate }}</td>
|
||||
<td>{{ currentAccountData.fieldOfficerName ? currentAccountData.fieldOfficerName : 'Unassigned' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Currency' | translate }}</td>
|
||||
<td>{{ currentAccountData.currency.name }} [{{ currentAccountData.currency.code }}]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Nominal Interest Rate' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
@if (currentAccountData.nominalAnnualInterestRate) {
|
||||
<span>{{ currentAccountData.nominalAnnualInterestRate | formatNumber }} %</span>
|
||||
}
|
||||
@if (!currentAccountData.nominalAnnualInterestRate) {
|
||||
<span>0 %</span>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
} @else {
|
||||
<div>
|
||||
<h4 class="table-headers">{{ 'labels.heading.Current Account Details' | translate }}</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Field Officer' | translate }}</td>
|
||||
<td>{{ currentAccountData.fieldOfficerName ? currentAccountData.fieldOfficerName : 'Unassigned' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Balance' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.summary.accountBalance | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
@if (!currentAccountData.status.rejected && !currentAccountData.status.submittedAndPendingApproval) {
|
||||
<div>
|
||||
<h4 class="table-headers">{{ 'labels.heading.Performance History' | translate }}</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
@if (currentAccountData.summary.totalDeposits) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Total Deposits' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.summary.totalDeposits | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalInterestEarned >= 0) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Total Interest Earned' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalInterestEarned
|
||||
| currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (isActive) {
|
||||
<div class="flex-49">
|
||||
<h4 class="table-headers">{{ 'labels.heading.Account Summary' | translate }}</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
@if (currentAccountData.summary.totalWithdrawals) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Total Withdrawls' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalWithdrawals | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalWithdrawalFees) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Withdrawals Fees' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalWithdrawalFees | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalAnnualFees) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Annual Fees' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.summary.totalAnnualFees | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalInterestEarned >= 0) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Earned' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalInterestEarned | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalInterestPosted) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Posted' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalInterestPosted | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.interestNotPosted >= 0) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Earned Not Posted' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.interestNotPosted | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.totalOverdraftInterestDerived) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest On Overdraft' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.totalOverdraftInterestDerived
|
||||
| currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.interestNotPosted < 0) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Overdraft Interest Not Posted' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{
|
||||
currentAccountData.summary.interestNotPosted | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.nominalAnnualInterestRate) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Nominal Interest Rate' | translate }}</td>
|
||||
<td class="r-amount">{{ currentAccountData.nominalAnnualInterestRate | formatNumber }} %</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Compounding Period' | translate }}</td>
|
||||
<td>{{ currentAccountData.interestCompoundingPeriodType.value | translateKey: 'catalogs' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Posting Period' | translate }}</td>
|
||||
<td>{{ currentAccountData.interestPostingPeriodType.value | translateKey: 'catalogs' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Calculated Using' | translate }}</td>
|
||||
<td>{{ currentAccountData.interestCalculationType.value | translateKey: 'catalogs' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Days in Year' | translate }}</td>
|
||||
<td>{{ currentAccountData.interestCalculationDaysInYearType.value | translateKey: 'catalogs' }}</td>
|
||||
</tr>
|
||||
@if (currentAccountData.withdrawalFee) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Withdrawal Fee' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.withdrawalFee.amount | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.lastActiveTransactionDate) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Last Active Transaction Date' | translate }}</td>
|
||||
<td>{{ currentAccountData.lastActiveTransactionDate | dateFormat }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (!(currentAccountData.subStatus.id === 0)) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Substatus' | translate }}</td>
|
||||
<td>{{ currentAccountData.subStatus.value }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.daysToInactive) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Days to Inactive' | translate }}</td>
|
||||
<td>{{ currentAccountData.daysToInactive }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.daysToDormancy) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Days to Dormancy' | translate }}</td>
|
||||
<td>{{ currentAccountData.daysToDormancy }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.daysToEscheat) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Days to Escheat' | translate }}</td>
|
||||
<td>{{ currentAccountData.daysToEscheat }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.annualFee) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Annual Fee' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.annualFee.amount | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.allowOverdraft) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Overdraft Limit' | translate }}</td>
|
||||
<td class="r-amount">
|
||||
{{ currentAccountData.overdraftLimit | currency: currency.code : 'symbol-narrow' : '1.2-2' }}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.allowOverdraft) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Minimum Overdraft Required for Interest Calculation' | translate }}</td>
|
||||
<td>
|
||||
{{
|
||||
currentAccountData.minOverdraftForInterestCalculation
|
||||
| currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.minBalanceForInterestCalculation) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Min Balance Required for Interest Calculation' | translate }}</td>
|
||||
<td>{{ currentAccountData.minBalanceForInterestCalculation | formatNumber }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.minRequiredBalance) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Minimum Required Balance' | translate }}</td>
|
||||
<td>{{ currentAccountData.minRequiredBalance | formatNumber }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.enforceMinRequiredBalance) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Enforce Minimum Required Balance' | translate }}</td>
|
||||
<td>{{ currentAccountData.enforceMinRequiredBalance | yesNo }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.summary.lastInterestCalculationDate) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Interest Recalculation Date' | translate }}</td>
|
||||
<td>{{ currentAccountData.summary.lastInterestCalculationDate | dateFormat }}</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.onHoldFunds) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.On Hold Funds' | translate }}</td>
|
||||
<td>
|
||||
<a *mifosxHasPermission="'READ_CURRENTACCOUNT'">{{
|
||||
currentAccountData.onHoldFunds | currency: currency.code : 'symbol-narrow' : '1.2-2'
|
||||
}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (currentAccountData.withHoldTax) {
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Withhold Tax Group' | translate }}</td>
|
||||
<td>{{ currentAccountData.taxGroup.name }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="flex-49">
|
||||
<h4 class="table-headers">{{ 'labels.heading.Account Summary' | translate }}</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.External Id' | translate }}</td>
|
||||
@if (currentAccountData.externalId) {
|
||||
<td>
|
||||
<mifosx-external-identifier
|
||||
externalId="{{ currentAccountData.externalId }}"
|
||||
></mifosx-external-identifier>
|
||||
</td>
|
||||
}
|
||||
@if (!currentAccountData.externalId) {
|
||||
<td>{{ 'labels.inputs.Not Provided' | translate }}</td>
|
||||
}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Activated On' | translate }}</td>
|
||||
<td>
|
||||
{{
|
||||
currentAccountData.timeline.activatedOnDate
|
||||
? (currentAccountData.timeline.activatedOnDate | dateFormat)
|
||||
: 'Not Activated'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'labels.inputs.Currency' | translate }}</td>
|
||||
<td>{{ currentAccountData.currency.name }} [{{ currentAccountData.currency.code }}]</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
Reference in New Issue
Block a user