WEB-467 Interest Rates Field Allows Zero and Negative Values in Loan Product Creation Form

This commit is contained in:
Soni Jay
2025-12-30 08:43:10 +05:30
parent 7fad7ee756
commit 88b52c008b
15 changed files with 72 additions and 12 deletions
@@ -159,9 +159,12 @@
[min]="0"
[attr.disabled]="isZeroInterest()"
/>
<mat-error>
<mat-error *ngIf="loanProductTermsForm.get('minInterestRatePerPeriod')?.hasError('min')">
{{ 'labels.commons.Minimum Value must be' | translate }}
<strong>{{ 'labels.commons.greater equal to than 0' | translate }}</strong>
<strong>0</strong>
</mat-error>
<mat-error *ngIf="loanProductTermsForm.get('minInterestRatePerPeriod')?.hasError('pattern')">
{{ 'labels.commons.Only up to 6 decimal places allowed' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="flex-fill flex-23">
@@ -171,12 +174,20 @@
matInput
formControlName="interestRatePerPeriod"
required
[min]="0"
[attr.disabled]="isZeroInterest()"
/>
<mat-error>
<mat-error *ngIf="loanProductTermsForm.get('interestRatePerPeriod')?.hasError('required')">
{{ 'labels.catalogs.Default' | translate }} {{ 'labels.inputs.Nominal interest rate' | translate }}
<span class="text-danger">{{ 'labels.commons.is required' | translate }}</span>
</mat-error>
<mat-error *ngIf="loanProductTermsForm.get('interestRatePerPeriod')?.hasError('min')">
{{ 'labels.catalogs.Default' | translate }} {{ 'labels.inputs.Nominal interest rate' | translate }}
{{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
<strong>0</strong>
</mat-error>
<mat-error *ngIf="loanProductTermsForm.get('interestRatePerPeriod')?.hasError('pattern')">
{{ 'labels.commons.Only up to 6 decimal places allowed' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="flex-fill flex-23">
@@ -188,11 +199,17 @@
[min]="0"
[attr.disabled]="isZeroInterest()"
/>
<mat-error>
<mat-error *ngIf="loanProductTermsForm.get('maxInterestRatePerPeriod')?.hasError('min')">
{{ 'labels.commons.Minimum Value must be' | translate }}
<strong>0</strong>
</mat-error>
<mat-error *ngIf="loanProductTermsForm.errors?.['maxLessThanMin']">
{{ 'labels.commons.Maximum Value must be' | translate }}
<strong>{{ 'labels.commons.greater equal to than 0' | translate }}</strong>
{{ 'labels.commons.and must be greater than' | translate }}
<strong>{{ 'labels.commons.Minimum Principal' | translate }}</strong>
<strong>{{ 'labels.commons.greater equal to than' | translate }}</strong>
{{ 'labels.inputs.Minimum' | translate }}
</mat-error>
<mat-error *ngIf="loanProductTermsForm.get('maxInterestRatePerPeriod')?.hasError('pattern')">
{{ 'labels.commons.Only up to 6 decimal places allowed' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="flex-fill flex-23">
@@ -230,12 +230,28 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges {
allowApprovedDisbursedAmountsOverApplied: [false],
overAppliedCalculationType: [{ value: null, disabled: true }],
overAppliedNumber: [{ value: null, disabled: true }],
minInterestRatePerPeriod: [''],
minInterestRatePerPeriod: [
'',
[
Validators.min(0),
Validators.pattern(/^\d+([.,]\d{1,6})?$/)
]
],
interestRatePerPeriod: [
'',
Validators.required
[
Validators.required,
Validators.min(0),
Validators.pattern(/^\d+([.,]\d{1,6})?$/)
]
],
maxInterestRatePerPeriod: [
'',
[
Validators.min(0),
Validators.pattern(/^\d+([.,]\d{1,6})?$/)
]
],
maxInterestRatePerPeriod: [''],
interestRateFrequencyType: [
'',
Validators.required
@@ -487,7 +503,21 @@ export class LoanProductTermsStepComponent implements OnInit, OnChanges {
}
get loanProductTerms() {
return this.loanProductTermsForm.getRawValue();
const formValue = this.loanProductTermsForm.getRawValue();
// Normalize decimal separators: convert comma to dot for backend compatibility
const normalizeDecimal = (value: any) => {
if (typeof value === 'string' && value.includes(',')) {
return value.replace(',', '.');
}
return value;
};
return {
...formValue,
minInterestRatePerPeriod: normalizeDecimal(formValue.minInterestRatePerPeriod),
interestRatePerPeriod: normalizeDecimal(formValue.interestRatePerPeriod),
maxInterestRatePerPeriod: normalizeDecimal(formValue.maxInterestRatePerPeriod)
};
}
isZeroInterest(): boolean {