Skip to content

Commit 9ded425

Browse files
authored
Merge pull request #2829 from alberto-art3ch/WEB-446/validation-of-re-age-amount-during-submission
WEB-446: Validation of re-Age amount during submission
2 parents 88b7194 + 0308a7d commit 9ded425

File tree

19 files changed

+99
-34
lines changed

19 files changed

+99
-34
lines changed

src/app/directives/format-amount.directive.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export class FormatAmountDirective implements OnInit {
4242
) {}
4343

4444
parse(value: any) {
45+
if (value == '') {
46+
return '' + this.sufix;
47+
}
4548
return formatCurrency(value, this.locale, this.displaySymbol, this.currencyCode, this.digitsInfo) + this.sufix;
4649
}
4750
}

src/app/loans/loans-view/loan-account-actions/loan-reaging/loan-reaging.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
<div class="container mat-elevation-z8">
22
<mat-card>
3-
<form [formGroup]="reagingLoanForm" (ngSubmit)="submit()">
3+
<form [formGroup]="reagingLoanForm" (ngSubmit)="submit()" *ngIf="loanTransactionData !== null">
44
<mat-card-content>
55
<div class="layout-column">
6+
<mifosx-input-amount
7+
[currency]="loanTransactionData.currency"
8+
[isRequired]="false"
9+
[inputFormControl]="reagingLoanForm.controls.transactionAmount"
10+
[inputLabel]="'Transaction Amount'"
11+
[minVal]="0.01"
12+
[maxVal]="loanTransactionData.amount"
13+
>
14+
</mifosx-input-amount>
15+
616
<mat-form-field>
717
<mat-label>{{ 'labels.inputs.Number of Installments' | translate }}</mat-label>
818
<input type="number" matInput required formControlName="numberOfInstallments" />

src/app/loans/loans-view/loan-account-actions/loan-reaging/loan-reaging.component.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import { SettingsService } from 'app/settings/settings.service';
99
import { OptionData } from 'app/shared/models/option-data.model';
1010
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
1111
import { ReAgePreviewDialogComponent } from './re-age-preview-dialog/re-age-preview-dialog.component';
12+
import { InputAmountComponent } from 'app/shared/input-amount/input-amount.component';
13+
import { LoanTransactionTemplate } from 'app/loans/models/loan-transaction-type.model';
1214

1315
@Component({
1416
selector: 'mifosx-loan-reaging',
1517
templateUrl: './loan-reaging.component.html',
1618
styleUrls: ['./loan-reaging.component.scss'],
1719
imports: [
18-
...STANDALONE_SHARED_IMPORTS
20+
...STANDALONE_SHARED_IMPORTS,
21+
InputAmountComponent
1922
]
2023
})
2124
export class LoanReagingComponent implements OnInit {
@@ -34,7 +37,7 @@ export class LoanReagingComponent implements OnInit {
3437
/** Maximum Date allowed. */
3538
maxDate = new Date();
3639

37-
currencyCode: string = '';
40+
loanTransactionData: LoanTransactionTemplate | null = null;
3841

3942
constructor(
4043
private formBuilder: UntypedFormBuilder,
@@ -49,17 +52,13 @@ export class LoanReagingComponent implements OnInit {
4952
}
5053

5154
ngOnInit(): void {
55+
this.loanTransactionData = this.dataObject;
56+
5257
this.maxDate = this.settingsService.maxFutureDate;
5358

5459
this.reAgeReasonOptions = this.dataObject.reAgeReasonOptions;
5560
this.reAgeInterestHandlingOptions = this.dataObject.reAgeInterestHandlingOptions;
5661
this.periodFrequencyOptions = this.dataObject.periodFrequencyOptions;
57-
58-
const loanDetailsData = this.route.parent?.parent?.snapshot.data['loanDetailsData'];
59-
if (loanDetailsData?.currency?.code) {
60-
this.currencyCode = loanDetailsData.currency.code;
61-
}
62-
6362
this.createReagingLoanForm();
6463
}
6564

@@ -84,6 +83,10 @@ export class LoanReagingComponent implements OnInit {
8483
reAgeInterestHandling: [
8584
this.reAgeInterestHandlingOptions[0]
8685
],
86+
transactionAmount: [
87+
this.loanTransactionData.amount,
88+
[Validators.max(this.loanTransactionData.amount)]
89+
],
8790
note: '',
8891
externalId: '',
8992
reasonCodeValueId: null
@@ -116,7 +119,7 @@ export class LoanReagingComponent implements OnInit {
116119

117120
this.loanService.getReAgePreview(this.loanId, data).subscribe({
118121
next: (response: RepaymentSchedule) => {
119-
const currencyCode = response.currency?.code || this.currencyCode;
122+
const currencyCode = response.currency?.code || this.loanTransactionData.currency.code;
120123

121124
if (!currencyCode) {
122125
console.error('Currency code is not available in API response or loan details');

src/app/loans/models/loan-transaction-type.model.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { CodeValue, Currency } from 'app/shared/models/general.model';
2+
import { OptionData } from 'app/shared/models/option-data.model';
3+
14
export interface LoanTransactionType {
25
id: number;
36
code: string;
@@ -41,3 +44,17 @@ export interface LoanTransactionType {
4144
buyDownFeeAdjustment: boolean;
4245
buyDownFeeAmortizationAdjustment: boolean;
4346
}
47+
48+
export interface LoanTransactionTemplate {
49+
loanId: number;
50+
externalLoanId: string;
51+
type: LoanTransactionType;
52+
date: number[];
53+
currency: Currency;
54+
amount: number;
55+
netDisbursalAmount: number;
56+
manuallyReversed: boolean;
57+
reAgeReasonOptions: CodeValue[];
58+
periodFrequencyOptions: string[];
59+
reAgeInterestHandlingOptions: OptionData[];
60+
}

src/app/shared/input-amount/input-amount.component.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
<mat-hint class="right-hint" *ngIf="displayHint">{{
2121
inputFormControl.value | currency: currency.code : currency.displaySymbol : '1.2-2'
2222
}}</mat-hint>
23+
<mat-error *ngIf="minVal && inputFormControl.hasError('min')">
24+
{{ 'labels.inputs.Amount' | translate }} {{ 'labels.commons.Must be at least' | translate }} {{ minVal }}
25+
</mat-error>
26+
<mat-error *ngIf="maxVal && inputFormControl.hasError('max')">
27+
{{ 'labels.inputs.Amount' | translate }} {{ 'labels.commons.Must be less or equal to' | translate }} {{ maxVal }}
28+
</mat-error>
2329
</mat-form-field>
2430
<mat-form-field appearance="fill" class="flex-100" *ngIf="!isRequired">
2531
<mat-label>{{ 'labels.inputs.' + inputLabel | translate }}</mat-label>
@@ -37,4 +43,10 @@
3743
<mat-hint class="right-hint" *ngIf="displayHint">{{
3844
inputFormControl.value | currency: currency.code : currency.displaySymbol : '1.2-2'
3945
}}</mat-hint>
46+
<mat-error *ngIf="minVal && inputFormControl.hasError('min')">
47+
{{ 'labels.inputs.Amount' | translate }} {{ 'labels.commons.Must be at least' | translate }} {{ minVal }}
48+
</mat-error>
49+
<mat-error *ngIf="maxVal && inputFormControl.hasError('max')">
50+
{{ 'labels.inputs.Amount' | translate }} {{ 'labels.commons.Must be less or equal to' | translate }} {{ maxVal }}
51+
</mat-error>
4052
</mat-form-field>

src/app/shared/input-amount/input-amount.component.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Component, Input } from '@angular/core';
22
import { Currency } from '../models/general.model';
3-
import { UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
4-
import { NgIf, CurrencyPipe } from '@angular/common';
5-
import { MatFormField, MatLabel, MatError, MatHint, MatSuffix } from '@angular/material/form-field';
3+
import { UntypedFormControl } from '@angular/forms';
4+
import { CurrencyPipe } from '@angular/common';
5+
import { MatHint } from '@angular/material/form-field';
66
import { FormatAmountDirective } from '../../directives/format-amount.directive';
77
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
88

@@ -22,6 +22,8 @@ export class InputAmountComponent {
2222
@Input() currency: Currency;
2323
@Input() inputLabel: string;
2424
@Input() inputFormControl: UntypedFormControl;
25+
@Input() minVal: number;
26+
@Input() maxVal: number;
2527

2628
displayHint = false;
2729

@@ -39,12 +41,4 @@ export class InputAmountComponent {
3941
}
4042
return true;
4143
}
42-
43-
inputBlur(): void {
44-
this.displayHint = false;
45-
}
46-
47-
inputFocus(): void {
48-
this.displayHint = true;
49-
}
5044
}

src/assets/translations/cs-CS.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,9 @@
803803
"required and cannot be negative": "požadováno a nemůže být záporné",
804804
"should": "by měl",
805805
"on": "na",
806-
"Password validation": "Heslo by mělo obsahovat minimálně {{minchar}} znaků, které by měly obsahovat 1 velké písmeno, malé písmeno a speciální znak a nemělo by se skládat z opakujících se znaků nebo mezer."
806+
"Password validation": "Heslo by mělo obsahovat minimálně {{minchar}} znaků, které by měly obsahovat 1 velké písmeno, malé písmeno a speciální znak a nemělo by se skládat z opakujících se znaků nebo mezer.",
807+
"Must be at least": "Musí být alespoň",
808+
"Must be less or equal to": "Musí být menší nebo rovno"
807809
},
808810
"heading": {
809811
"Account Linked Financial": "Seznam účtů spojených s různými finančními aktivitami. Chcete-li vědět více, klikněte:",

src/assets/translations/de-DE.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,9 @@
803803
"required and cannot be negative": "erforderlich und darf nicht negativ sein",
804804
"should": "sollen",
805805
"on": "An",
806-
"Password validation": "Das Passwort sollte mindestens {{michar}} Zeichen enthalten, aus 1 Großbuchstaben, Kleinbuchstaben und Sonderzeichen bestehen und darf nicht aus wiederholten Zeichen oder Leerzeichen bestehen"
806+
"Password validation": "Das Passwort sollte mindestens {{michar}} Zeichen enthalten, aus 1 Großbuchstaben, Kleinbuchstaben und Sonderzeichen bestehen und darf nicht aus wiederholten Zeichen oder Leerzeichen bestehen",
807+
"Must be at least": "Muss mindestens",
808+
"Must be less or equal to": "Muss kleiner oder gleich sein"
807809
},
808810
"heading": {
809811
"Account Linked Financial": "Liste der Konten, die mit verschiedenen Finanzaktivitäten verknüpft sind. Um mehr zu erfahren, klicken Sie:",

src/assets/translations/en-US.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,9 @@
807807
"required and cannot be negative": "required and cannot be negative",
808808
"should": "should",
809809
"on": "on",
810-
"Password validation": "The password should contain a minimum of {{minchar}} characters, including 1 uppercase, 1 lowercase and a special character and should not include repeated characters or spaces."
810+
"Password validation": "The password should contain a minimum of {{minchar}} characters, including 1 uppercase, 1 lowercase and a special character and should not include repeated characters or spaces.",
811+
"Must be at least": "Must be at least",
812+
"Must be less or equal to": "Must be less or equal to"
811813
},
812814
"heading": {
813815
"Account Linked Financial": "List of accounts linked to different financial activities. To know more click:",

src/assets/translations/es-CL.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,9 @@
802802
"required and cannot be negative": "requerido y no puede ser negativo",
803803
"should": "debería",
804804
"on": "en",
805-
"Password validation": "La contraseña debe contener un mínimo de {{minchar}} caracteres, que deben incluir 1 carácter mayúscula, minúscula y especial y no debe constar de caracteres repetidos ni espacios en blanco."
805+
"Password validation": "La contraseña debe contener un mínimo de {{minchar}} caracteres, que deben incluir 1 carácter mayúscula, minúscula y especial y no debe constar de caracteres repetidos ni espacios en blanco.",
806+
"Must be at least": "Debe ser al menos",
807+
"Must be less or equal to": "Debe ser menor o igual a"
806808
},
807809
"heading": {
808810
"Account Linked Financial": "Listado de cuentas vinculadas a diferentes actividades financieras. Para saber más haga clic en:",

0 commit comments

Comments
 (0)