WEB-661 Fix currency multiples fields sending empty strings to API and add optional checkbox controls (#3085)

This commit is contained in:
Soni Jay
2026-02-03 19:23:32 -06:00
committed by GitHub
parent 5f375583a5
commit 744826148b
31 changed files with 387 additions and 135 deletions
@@ -32,14 +32,20 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-48"> <mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t checkbox-align-center">
<mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label> {{ 'labels.inputs.Set the fixed deposit installment in multiples of' | translate }}
<input type="number" matInput formControlName="inMultiplesOf" /> </mat-checkbox>
<mat-error>
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }} @if (fixedDepositProductCurrencyForm.value.setMultiples) {
<strong>{{ 'labels.commons.required' | translate }}</strong> <mat-form-field class="flex-48">
</mat-error> <mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label>
</mat-form-field> <input type="number" min="1" matInput formControlName="inMultiplesOf" />
<mat-error>
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
}
</div> </div>
<div class="layout-row align-center gap-2percent margin-t responsive-column"> <div class="layout-row align-center gap-2percent margin-t responsive-column">
@@ -9,3 +9,7 @@
.margin-t { .margin-t {
margin-top: 1em; margin-top: 1em;
} }
.checkbox-align-center {
align-items: center;
}
@@ -6,9 +6,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import { Component, OnInit, Input, inject } from '@angular/core'; import { Component, OnInit, Input, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { startWith } from 'rxjs/operators';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper'; import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
import { MatCheckbox } from '@angular/material/checkbox';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -20,11 +23,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
...STANDALONE_SHARED_IMPORTS, ...STANDALONE_SHARED_IMPORTS,
MatStepperPrevious, MatStepperPrevious,
FaIconComponent, FaIconComponent,
MatStepperNext MatStepperNext,
MatCheckbox
] ]
}) })
export class FixedDepositProductCurrencyStepComponent implements OnInit { export class FixedDepositProductCurrencyStepComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder); private formBuilder = inject(UntypedFormBuilder);
private destroyRef = inject(DestroyRef);
@Input() fixedDepositProductsTemplate: any; @Input() fixedDepositProductsTemplate: any;
@@ -39,18 +44,14 @@ export class FixedDepositProductCurrencyStepComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.currencyData = this.fixedDepositProductsTemplate.currencyOptions; this.currencyData = this.fixedDepositProductsTemplate.currencyOptions;
if (!(this.fixedDepositProductsTemplate === undefined) && this.fixedDepositProductsTemplate.id) { this.fixedDepositProductCurrencyForm.patchValue({
this.fixedDepositProductCurrencyForm.patchValue({ currencyCode: this.fixedDepositProductsTemplate.currency?.code || this.currencyData[0].code,
currencyCode: this.fixedDepositProductsTemplate.currency.code, digitsAfterDecimal: this.fixedDepositProductsTemplate.digitsAfterDecimal ?? '',
digitsAfterDecimal: this.fixedDepositProductsTemplate.currency.decimalPlaces, setMultiples: !!this.fixedDepositProductsTemplate.inMultiplesOf,
inMultiplesOf: this.fixedDepositProductsTemplate.currency.inMultiplesOf inMultiplesOf: this.fixedDepositProductsTemplate.inMultiplesOf ?? ''
}); });
} else {
this.fixedDepositProductCurrencyForm.patchValue({ this.setupConditionalValidation();
currencyCode: this.currencyData[0].code,
digitsAfterDecimal: 2
});
}
} }
createFixedDepositProductCurrencyForm() { createFixedDepositProductCurrencyForm() {
@@ -61,13 +62,47 @@ export class FixedDepositProductCurrencyStepComponent implements OnInit {
], ],
digitsAfterDecimal: [ digitsAfterDecimal: [
'', '',
Validators.required [
Validators.required,
Validators.min(0)
]
], ],
setMultiples: [false],
inMultiplesOf: [''] inMultiplesOf: ['']
}); });
} }
setupConditionalValidation() {
const inMultiplesOfControl = this.fixedDepositProductCurrencyForm.get('inMultiplesOf');
const setMultiplesControl = this.fixedDepositProductCurrencyForm.get('setMultiples');
setMultiplesControl?.valueChanges
.pipe(startWith(setMultiplesControl.value), takeUntilDestroyed(this.destroyRef))
.subscribe((checked) => {
if (checked) {
inMultiplesOfControl?.setValidators([
Validators.required,
Validators.min(1)
]);
} else {
inMultiplesOfControl?.clearValidators();
inMultiplesOfControl?.setValue('');
}
inMultiplesOfControl?.updateValueAndValidity();
});
}
get fixedDepositProductCurrency() { get fixedDepositProductCurrency() {
return this.fixedDepositProductCurrencyForm.value; const formValue = this.fixedDepositProductCurrencyForm.value;
const result: any = {
currencyCode: formValue.currencyCode,
digitsAfterDecimal: formValue.digitsAfterDecimal
};
if (formValue.inMultiplesOf !== '' && formValue.inMultiplesOf !== null && formValue.inMultiplesOf !== undefined) {
result.inMultiplesOf = formValue.inMultiplesOf;
}
return result;
} }
} }
@@ -37,13 +37,17 @@
<div class="layout-row flex-100"> <div class="layout-row flex-100">
<span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span> <span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span>
<span class="flex-60">{{ fixedDepositProduct.digitsAfterDecimal }}</span> <span class="flex-60">{{
fixedDepositProduct.digitsAfterDecimal ?? fixedDepositProduct.currency?.decimalPlaces
}}</span>
</div> </div>
<div class="layout-row flex-100"> @if (fixedDepositProduct.inMultiplesOf) {
<span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span> <div class="layout-row flex-100">
<span class="flex-60">{{ fixedDepositProduct.inMultiplesOf }}</span> <span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span>
</div> <span class="flex-60">{{ fixedDepositProduct.inMultiplesOf }}</span>
</div>
}
<h3 class="mat-h3 flex-100">{{ 'labels.heading.Terms' | translate }}</h3> <h3 class="mat-h3 flex-100">{{ 'labels.heading.Terms' | translate }}</h3>
@@ -47,7 +47,7 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t"> <mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t align-center">
{{ 'labels.inputs.Set the multiples of the loan and its installment' | translate }} {{ 'labels.inputs.Set the multiples of the loan and its installment' | translate }}
</mat-checkbox> </mat-checkbox>
@@ -9,3 +9,7 @@
.margin-t { .margin-t {
margin-top: 1em; margin-top: 1em;
} }
.align-center {
align-items: center;
}
@@ -42,19 +42,26 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-48"> <mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t align-items-center">
<mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label> {{ 'labels.inputs.Set the recurring deposit installment in multiples of' | translate }}
<input </mat-checkbox>
type="number"
matInput @if (recurringDepositProductCurrencyForm.value.setMultiples) {
formControlName="inMultiplesOf" <mat-form-field class="flex-48">
matTooltip="{{ 'tooltips.Enter multiples of currency value' | translate }}" <mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label>
/> <input
<mat-error> type="number"
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }} min="1"
<strong>{{ 'labels.commons.required' | translate }}</strong> matInput
</mat-error> formControlName="inMultiplesOf"
</mat-form-field> matTooltip="{{ 'tooltips.Enter multiples of currency value' | translate }}"
/>
<mat-error>
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
}
</div> </div>
<div class="layout-row align-center gap-2percent margin-t responsive-column"> <div class="layout-row align-center gap-2percent margin-t responsive-column">
@@ -9,3 +9,7 @@
.margin-t { .margin-t {
margin-top: 1em; margin-top: 1em;
} }
.align-items-center {
align-items: center;
}
@@ -6,12 +6,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import { Component, OnInit, Input, inject } from '@angular/core'; import { Component, OnInit, Input, inject, DestroyRef } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatTooltip } from '@angular/material/tooltip'; import { MatTooltip } from '@angular/material/tooltip';
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper'; import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
import { MatCheckbox } from '@angular/material/checkbox';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({ @Component({
selector: 'mifosx-recurring-deposit-product-currency-step', selector: 'mifosx-recurring-deposit-product-currency-step',
@@ -22,11 +24,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
MatTooltip, MatTooltip,
MatStepperPrevious, MatStepperPrevious,
FaIconComponent, FaIconComponent,
MatStepperNext MatStepperNext,
MatCheckbox
] ]
}) })
export class RecurringDepositProductCurrencyStepComponent implements OnInit { export class RecurringDepositProductCurrencyStepComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder); private formBuilder = inject(UntypedFormBuilder);
private destroyRef = inject(DestroyRef);
@Input() recurringDepositProductsTemplate: any; @Input() recurringDepositProductsTemplate: any;
@@ -40,17 +44,25 @@ export class RecurringDepositProductCurrencyStepComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.currencyData = this.recurringDepositProductsTemplate.currencyOptions; this.currencyData = this.recurringDepositProductsTemplate.currencyOptions;
if (!(this.recurringDepositProductsTemplate === undefined) && this.recurringDepositProductsTemplate.id) {
this.recurringDepositProductCurrencyForm.patchValue({ this.recurringDepositProductCurrencyForm.patchValue({
currencyCode: this.recurringDepositProductsTemplate.currency.code, currencyCode: this.recurringDepositProductsTemplate.currency?.code || this.currencyData[0].code,
digitsAfterDecimal: this.recurringDepositProductsTemplate.currency.decimalPlaces, digitsAfterDecimal: this.recurringDepositProductsTemplate.digitsAfterDecimal ?? '',
inMultiplesOf: this.recurringDepositProductsTemplate.currency.inMultiplesOf setMultiples: !!this.recurringDepositProductsTemplate.inMultiplesOf,
}); inMultiplesOf: this.recurringDepositProductsTemplate.inMultiplesOf ?? ''
} else { });
this.recurringDepositProductCurrencyForm.patchValue({
currencyCode: this.currencyData[0].code, this.setupConditionalValidation();
digitsAfterDecimal: 2
}); // Apply initial validators based on the patched setMultiples value
const inMultiplesOfControl = this.recurringDepositProductCurrencyForm.get('inMultiplesOf');
const setMultiplesControl = this.recurringDepositProductCurrencyForm.get('setMultiples');
if (setMultiplesControl?.value) {
inMultiplesOfControl?.setValidators([
Validators.required,
Validators.min(1)
]);
inMultiplesOfControl?.updateValueAndValidity();
} }
} }
@@ -62,13 +74,45 @@ export class RecurringDepositProductCurrencyStepComponent implements OnInit {
], ],
digitsAfterDecimal: [ digitsAfterDecimal: [
'', '',
Validators.required [
Validators.required,
Validators.min(0)
]
], ],
setMultiples: [false],
inMultiplesOf: [''] inMultiplesOf: ['']
}); });
} }
setupConditionalValidation() {
const inMultiplesOfControl = this.recurringDepositProductCurrencyForm.get('inMultiplesOf');
const setMultiplesControl = this.recurringDepositProductCurrencyForm.get('setMultiples');
setMultiplesControl?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((checked) => {
if (checked) {
inMultiplesOfControl?.setValidators([
Validators.required,
Validators.min(1)
]);
} else {
inMultiplesOfControl?.clearValidators();
inMultiplesOfControl?.setValue('');
}
inMultiplesOfControl?.updateValueAndValidity();
});
}
get recurringDepositProductCurrency() { get recurringDepositProductCurrency() {
return this.recurringDepositProductCurrencyForm.value; const formValue = this.recurringDepositProductCurrencyForm.value;
const result: any = {
currencyCode: formValue.currencyCode,
digitsAfterDecimal: formValue.digitsAfterDecimal
};
if (formValue.inMultiplesOf !== '' && formValue.inMultiplesOf !== null && formValue.inMultiplesOf !== undefined) {
result.inMultiplesOf = formValue.inMultiplesOf;
}
return result;
} }
} }
@@ -37,13 +37,17 @@
<div class="layout-row flex-100"> <div class="layout-row flex-100">
<span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span> <span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span>
<span class="flex-60">{{ recurringDepositProduct.digitsAfterDecimal }}</span> <span class="flex-60">{{
recurringDepositProduct.digitsAfterDecimal ?? recurringDepositProduct.currency?.decimalPlaces
}}</span>
</div> </div>
<div class="layout-row flex-100"> @if (recurringDepositProduct.inMultiplesOf) {
<span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span> <div class="layout-row flex-100">
<span class="flex-60">{{ recurringDepositProduct.inMultiplesOf }}</span> <span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span>
</div> <span class="flex-60">{{ recurringDepositProduct.inMultiplesOf }}</span>
</div>
}
<h3 class="mat-h3 flex-100">{{ 'labels.heading.Terms' | translate }}</h3> <h3 class="mat-h3 flex-100">{{ 'labels.heading.Terms' | translate }}</h3>
@@ -43,21 +43,26 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-48"> <mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t checkbox-align-center">
<mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label> {{ 'labels.inputs.Set the saving installment in multiples of' | translate }}
<input </mat-checkbox>
type="number"
min="1" @if (savingProductCurrencyForm.value.setMultiples) {
matInput <mat-form-field class="flex-48">
matTooltip="{{ 'tooltips.Amount to be rounded off' | translate }}" <mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label>
formControlName="inMultiplesOf" <input
required type="number"
/> min="1"
<mat-error> matInput
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }} matTooltip="{{ 'tooltips.Amount to be rounded off' | translate }}"
<strong>{{ 'labels.commons.required' | translate }}</strong> formControlName="inMultiplesOf"
</mat-error> />
</mat-form-field> <mat-error>
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
}
</div> </div>
<div class="layout-row align-center gap-2percent margin-t responsive-column"> <div class="layout-row align-center gap-2percent margin-t responsive-column">
@@ -9,3 +9,7 @@
.margin-t { .margin-t {
margin-top: 1em; margin-top: 1em;
} }
.checkbox-align-center {
align-items: center;
}
@@ -6,10 +6,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import { Component, OnInit, Input, inject } from '@angular/core'; import { Component, OnInit, Input, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatTooltip } from '@angular/material/tooltip'; import { MatTooltip } from '@angular/material/tooltip';
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper'; import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
import { MatCheckbox } from '@angular/material/checkbox';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -22,11 +24,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
MatTooltip, MatTooltip,
MatStepperPrevious, MatStepperPrevious,
FaIconComponent, FaIconComponent,
MatStepperNext MatStepperNext,
MatCheckbox
] ]
}) })
export class SavingProductCurrencyStepComponent implements OnInit { export class SavingProductCurrencyStepComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder); private formBuilder = inject(UntypedFormBuilder);
private destroyRef = inject(DestroyRef);
@Input() savingProductsTemplate: any; @Input() savingProductsTemplate: any;
@@ -43,11 +47,12 @@ export class SavingProductCurrencyStepComponent implements OnInit {
this.savingProductCurrencyForm.patchValue({ this.savingProductCurrencyForm.patchValue({
currencyCode: this.savingProductsTemplate.currency.code || this.currencyData[0].code, currencyCode: this.savingProductsTemplate.currency.code || this.currencyData[0].code,
digitsAfterDecimal: this.savingProductsTemplate.currency.code digitsAfterDecimal: this.savingProductsTemplate.digitsAfterDecimal ?? '',
? this.savingProductsTemplate.currency.decimalPlaces setMultiples: !!this.savingProductsTemplate.inMultiplesOf,
: 2, inMultiplesOf: this.savingProductsTemplate.inMultiplesOf ?? ''
inMultiplesOf: this.savingProductsTemplate.currency.inMultiplesOf || ''
}); });
this.setupConditionalValidation();
} }
createSavingProductCurrencyForm() { createSavingProductCurrencyForm() {
@@ -63,17 +68,47 @@ export class SavingProductCurrencyStepComponent implements OnInit {
Validators.min(0) Validators.min(0)
] ]
], ],
inMultiplesOf: [ setMultiples: [false],
'', inMultiplesOf: ['']
[ });
}
setupConditionalValidation() {
const inMultiplesOfControl = this.savingProductCurrencyForm.get('inMultiplesOf');
const setMultiplesControl = this.savingProductCurrencyForm.get('setMultiples');
if (setMultiplesControl?.value) {
inMultiplesOfControl?.setValidators([
Validators.required,
Validators.min(1)
]);
inMultiplesOfControl?.updateValueAndValidity();
}
setMultiplesControl?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((checked) => {
if (checked) {
inMultiplesOfControl?.setValidators([
Validators.required, Validators.required,
Validators.min(1) Validators.min(1)
] ]);
] } else {
inMultiplesOfControl?.clearValidators();
inMultiplesOfControl?.setValue('');
}
inMultiplesOfControl?.updateValueAndValidity();
}); });
} }
get savingProductCurrency() { get savingProductCurrency() {
return this.savingProductCurrencyForm.value; const formValue = this.savingProductCurrencyForm.value;
const result: any = {
currencyCode: formValue.currencyCode,
digitsAfterDecimal: formValue.digitsAfterDecimal
};
if (formValue.inMultiplesOf !== '' && formValue.inMultiplesOf !== null && formValue.inMultiplesOf !== undefined) {
result.inMultiplesOf = formValue.inMultiplesOf;
}
return result;
} }
} }
@@ -37,13 +37,15 @@
<div class="flex-100 layout-row"> <div class="flex-100 layout-row">
<span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span> <span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span>
<span class="flex-60">{{ savingProduct.digitsAfterDecimal }}</span> <span class="flex-60">{{ savingProduct.digitsAfterDecimal ?? savingProduct.currency?.decimalPlaces }}</span>
</div> </div>
<div class="flex-100 layout-row"> @if (savingProduct.inMultiplesOf) {
<span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span> <div class="flex-100 layout-row">
<span class="flex-60">{{ savingProduct.inMultiplesOf }}</span> <span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span>
</div> <span class="flex-60">{{ savingProduct.inMultiplesOf }}</span>
</div>
}
<h3 class="mat-h3 flex-100">{{ 'labels.inputs.Terms' | translate }}</h3> <h3 class="mat-h3 flex-100">{{ 'labels.inputs.Terms' | translate }}</h3>
@@ -43,21 +43,26 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-48"> <mat-checkbox labelPosition="before" formControlName="setMultiples" class="flex-98 margin-t align-items-center">
<mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label> {{ 'labels.inputs.Set the share installment in multiples of' | translate }}
<input </mat-checkbox>
type="number"
min="1" @if (shareProductCurrencyForm.value.setMultiples) {
matInput <mat-form-field class="flex-48">
matTooltip="{{ 'tooltips.Amount to be rounded off' | translate }}" <mat-label>{{ 'labels.inputs.Currency in multiples of' | translate }}</mat-label>
formControlName="inMultiplesOf" <input
required type="number"
/> min="1"
<mat-error> matInput
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }} matTooltip="{{ 'tooltips.Amount to be rounded off' | translate }}"
<strong>{{ 'labels.commons.required' | translate }}</strong> formControlName="inMultiplesOf"
</mat-error> />
</mat-form-field> <mat-error>
{{ 'labels.inputs.Currency in multiples of' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
}
</div> </div>
<div class="layout-row align-center gap-2percent margin-t responsive-column"> <div class="layout-row align-center gap-2percent margin-t responsive-column">
@@ -9,3 +9,7 @@
.margin-t { .margin-t {
margin-top: 1em; margin-top: 1em;
} }
.align-items-center {
align-items: center;
}
@@ -6,10 +6,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
import { Component, OnInit, Input, inject } from '@angular/core'; import { Component, OnInit, Input, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatTooltip } from '@angular/material/tooltip'; import { MatTooltip } from '@angular/material/tooltip';
import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper'; import { MatStepperPrevious, MatStepperNext } from '@angular/material/stepper';
import { MatCheckbox } from '@angular/material/checkbox';
import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -22,11 +24,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
MatTooltip, MatTooltip,
MatStepperPrevious, MatStepperPrevious,
FaIconComponent, FaIconComponent,
MatStepperNext MatStepperNext,
MatCheckbox
] ]
}) })
export class ShareProductCurrencyStepComponent implements OnInit { export class ShareProductCurrencyStepComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder); private formBuilder = inject(UntypedFormBuilder);
private destroyRef = inject(DestroyRef);
@Input() shareProductsTemplate: any; @Input() shareProductsTemplate: any;
@@ -41,18 +45,14 @@ export class ShareProductCurrencyStepComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.currencyData = this.shareProductsTemplate.currencyOptions; this.currencyData = this.shareProductsTemplate.currencyOptions;
if (this.shareProductsTemplate.currency) { this.shareProductCurrencyForm.patchValue({
this.shareProductCurrencyForm.patchValue({ currencyCode: this.shareProductsTemplate.currency?.code || this.currencyData[0].code,
currencyCode: this.shareProductsTemplate.currency.code, digitsAfterDecimal: this.shareProductsTemplate.digitsAfterDecimal ?? '',
digitsAfterDecimal: this.shareProductsTemplate.currency.decimalPlaces, setMultiples: !!this.shareProductsTemplate.inMultiplesOf,
inMultiplesOf: this.shareProductsTemplate.currency.inMultiplesOf inMultiplesOf: this.shareProductsTemplate.inMultiplesOf ?? ''
}); });
} else {
this.shareProductCurrencyForm.patchValue({ this.setupConditionalValidation();
currencyCode: this.currencyData[0].code,
digitsAfterDecimal: 2
});
}
} }
createShareProductCurrencyForm() { createShareProductCurrencyForm() {
@@ -68,17 +68,48 @@ export class ShareProductCurrencyStepComponent implements OnInit {
Validators.min(0) Validators.min(0)
] ]
], ],
inMultiplesOf: [ setMultiples: [false],
'', inMultiplesOf: ['']
[ });
}
setupConditionalValidation() {
const inMultiplesOfControl = this.shareProductCurrencyForm.get('inMultiplesOf');
const setMultiplesControl = this.shareProductCurrencyForm.get('setMultiples');
const applyInMultiplesValidators = (checked: boolean) => {
if (checked) {
inMultiplesOfControl?.setValidators([
Validators.required, Validators.required,
Validators.min(1) Validators.min(1)
] ]);
] } else {
inMultiplesOfControl?.clearValidators();
inMultiplesOfControl?.setValue('');
}
inMultiplesOfControl?.updateValueAndValidity();
};
// Apply validators based on initial value
applyInMultiplesValidators(setMultiplesControl?.value);
// Listen for changes
setMultiplesControl?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((checked) => {
applyInMultiplesValidators(checked);
}); });
} }
get shareProductCurrency() { get shareProductCurrency() {
return this.shareProductCurrencyForm.value; const formValue = this.shareProductCurrencyForm.value;
const result: any = {
currencyCode: formValue.currencyCode,
digitsAfterDecimal: formValue.digitsAfterDecimal
};
if (formValue.inMultiplesOf !== '' && formValue.inMultiplesOf !== null && formValue.inMultiplesOf !== undefined) {
result.inMultiplesOf = formValue.inMultiplesOf;
}
return result;
} }
} }
@@ -37,13 +37,15 @@
<div class="flex-fill layout-row"> <div class="flex-fill layout-row">
<span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span> <span class="flex-40">{{ 'labels.inputs.Decimal Places' | translate }}:</span>
<span class="flex-60">{{ shareProduct.digitsAfterDecimal }}</span> <span class="flex-60">{{ shareProduct.digitsAfterDecimal ?? shareProduct.currency?.decimalPlaces }}</span>
</div> </div>
<div class="flex-fill layout-row"> @if (shareProduct.inMultiplesOf) {
<span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span> <div class="flex-fill layout-row">
<span class="flex-60">{{ shareProduct.inMultiplesOf }}</span> <span class="flex-40">{{ 'labels.inputs.Currency in multiples of' | translate }}:</span>
</div> <span class="flex-60">{{ shareProduct.inMultiplesOf }}</span>
</div>
}
<h3 class="mat-h3 flex-fill">{{ 'labels.heading.Terms' | translate }}</h3> <h3 class="mat-h3 flex-fill">{{ 'labels.heading.Terms' | translate }}</h3>
+4
View File
@@ -1579,6 +1579,10 @@
"Currency Name": "Název měny", "Currency Name": "Název měny",
"Currency in multiples of": "Měna v násobcích", "Currency in multiples of": "Měna v násobcích",
"Set the multiples of the loan and its installment": "Nastavit násobky půjčky a její splátky", "Set the multiples of the loan and its installment": "Nastavit násobky půjčky a její splátky",
"Set the saving installment in multiples of": "Nastavit splátku úspor v násobcích",
"Set the share installment in multiples of": "Nastavit splátku akcií v násobcích",
"Set the fixed deposit installment in multiples of": "Nastavit splátku pevného vkladu v násobcích",
"Set the recurring deposit installment in multiples of": "Nastavit splátku opakovaného vkladu v násobcích",
"Current Balance": "Aktuální zůstatek", "Current Balance": "Aktuální zůstatek",
"Current Balances": "Aktuální zůstatky", "Current Balances": "Aktuální zůstatky",
"Current Business Date": "Aktuální obchodní datum", "Current Business Date": "Aktuální obchodní datum",
+4
View File
@@ -1581,6 +1581,10 @@
"Currency Name": "Währungsname", "Currency Name": "Währungsname",
"Currency in multiples of": "Währung in Vielfachen von", "Currency in multiples of": "Währung in Vielfachen von",
"Set the multiples of the loan and its installment": "Die Vielfachen des Darlehens und seiner Rate festlegen", "Set the multiples of the loan and its installment": "Die Vielfachen des Darlehens und seiner Rate festlegen",
"Set the saving installment in multiples of": "Die Sparrate in Vielfachen festlegen",
"Set the share installment in multiples of": "Die Aktienrate in Vielfachen festlegen",
"Set the fixed deposit installment in multiples of": "Die Festgeldrate in Vielfachen festlegen",
"Set the recurring deposit installment in multiples of": "Die wiederkehrende Einlage in Vielfachen festlegen",
"Current Balance": "Aktueller Kontostand", "Current Balance": "Aktueller Kontostand",
"Current Balances": "Aktuelle Guthaben", "Current Balances": "Aktuelle Guthaben",
"Current Business Date": "Aktuelles Geschäftsdatum", "Current Business Date": "Aktuelles Geschäftsdatum",
+4
View File
@@ -1585,6 +1585,10 @@
"Currency Name": "Currency Name", "Currency Name": "Currency Name",
"Currency in multiples of": "Currency in multiples of", "Currency in multiples of": "Currency in multiples of",
"Set the multiples of the loan and its installment": "Set the multiples of the loan and its installment", "Set the multiples of the loan and its installment": "Set the multiples of the loan and its installment",
"Set the saving installment in multiples of": "Set the saving installment in multiples",
"Set the share installment in multiples of": "Set the share installment in multiples",
"Set the fixed deposit installment in multiples of": "Set the fixed deposit installment in multiples",
"Set the recurring deposit installment in multiples of": "Set the recurring deposit installment in multiples",
"Current Balance": "Current Balance", "Current Balance": "Current Balance",
"Current Balances": "Current Balances", "Current Balances": "Current Balances",
"Current Business Date": "Current Business Date", "Current Business Date": "Current Business Date",
+4
View File
@@ -1581,6 +1581,10 @@
"Currency Name": "Nombre de la moneda", "Currency Name": "Nombre de la moneda",
"Currency in multiples of": "Moneda en múltiplos de", "Currency in multiples of": "Moneda en múltiplos de",
"Set the multiples of the loan and its installment": "Establecer los múltiplos del préstamo y su cuota", "Set the multiples of the loan and its installment": "Establecer los múltiplos del préstamo y su cuota",
"Set the saving installment in multiples of": "Establecer la cuota de ahorro en múltiplos de",
"Set the share installment in multiples of": "Establecer la cuota de acciones en múltiplos de",
"Set the fixed deposit installment in multiples of": "Establecer la cuota de depósito fijo en múltiplos de",
"Set the recurring deposit installment in multiples of": "Establecer la cuota de depósito recurrente en múltiplos de",
"Current Balance": "Saldo actual", "Current Balance": "Saldo actual",
"Current Balances": "Saldos actuales", "Current Balances": "Saldos actuales",
"Current Business Date": "Fecha del sistema actual", "Current Business Date": "Fecha del sistema actual",
+4
View File
@@ -1580,6 +1580,10 @@
"Currency Name": "Nombre de la moneda", "Currency Name": "Nombre de la moneda",
"Currency in multiples of": "Moneda en múltiplos de", "Currency in multiples of": "Moneda en múltiplos de",
"Set the multiples of the loan and its installment": "Establecer los múltiplos del crédito y su cuota", "Set the multiples of the loan and its installment": "Establecer los múltiplos del crédito y su cuota",
"Set the saving installment in multiples of": "Establecer la cuota de ahorro en múltiplos de",
"Set the share installment in multiples of": "Establecer la cuota de acciones en múltiplos de",
"Set the fixed deposit installment in multiples of": "Establecer la cuota de depósito fijo en múltiplos de",
"Set the recurring deposit installment in multiples of": "Establecer la cuota de depósito recurrente en múltiplos de",
"Current Balance": "Saldo actual", "Current Balance": "Saldo actual",
"Current Balances": "Saldos actuales", "Current Balances": "Saldos actuales",
"Current Business Date": "Fecha del sistema actual", "Current Business Date": "Fecha del sistema actual",
+4
View File
@@ -1581,6 +1581,10 @@
"Currency Name": "Nom de la devise", "Currency Name": "Nom de la devise",
"Currency in multiples of": "Monnaie en multiples de", "Currency in multiples of": "Monnaie en multiples de",
"Set the multiples of the loan and its installment": "Définir les multiples du prêt et de son versement", "Set the multiples of the loan and its installment": "Définir les multiples du prêt et de son versement",
"Set the saving installment in multiples of": "Définir le versement d'épargne en multiples de",
"Set the share installment in multiples of": "Définir le versement d'actions en multiples de",
"Set the fixed deposit installment in multiples of": "Définir le versement de dépôt fixe en multiples de",
"Set the recurring deposit installment in multiples of": "Définir le versement de dépôt récurrent en multiples de",
"Current Balance": "Solde actuel", "Current Balance": "Solde actuel",
"Current Balances": "Soldes courants", "Current Balances": "Soldes courants",
"Current Business Date": "Date d'ouverture actuelle", "Current Business Date": "Date d'ouverture actuelle",
+4
View File
@@ -1580,6 +1580,10 @@
"Currency Name": "Nome della valuta", "Currency Name": "Nome della valuta",
"Currency in multiples of": "Valuta in multipli di", "Currency in multiples of": "Valuta in multipli di",
"Set the multiples of the loan and its installment": "Imposta i multipli del prestito e della sua rata", "Set the multiples of the loan and its installment": "Imposta i multipli del prestito e della sua rata",
"Set the saving installment in multiples of": "Imposta la rata di risparmio in multipli di",
"Set the share installment in multiples of": "Imposta la rata delle azioni in multipli di",
"Set the fixed deposit installment in multiples of": "Imposta la rata del deposito fisso in multipli di",
"Set the recurring deposit installment in multiples of": "Imposta la rata del deposito ricorrente in multipli di",
"Current Balance": "Bilancio corrente", "Current Balance": "Bilancio corrente",
"Current Balances": "Saldi correnti", "Current Balances": "Saldi correnti",
"Current Business Date": "Data lavorativa corrente", "Current Business Date": "Data lavorativa corrente",
+4
View File
@@ -1582,6 +1582,10 @@
"Currency Name": "통화 이름", "Currency Name": "통화 이름",
"Currency in multiples of": "통화의 배수", "Currency in multiples of": "통화의 배수",
"Set the multiples of the loan and its installment": "대출 및 할부금의 배수 설정", "Set the multiples of the loan and its installment": "대출 및 할부금의 배수 설정",
"Set the saving installment in multiples of": "저축 할부금을 배수로 설정",
"Set the share installment in multiples of": "주식 할부금을 배수로 설정",
"Set the fixed deposit installment in multiples of": "정기 예금 할부금을 배수로 설정",
"Set the recurring deposit installment in multiples of": "반복 예금 할부금을 배수로 설정",
"Current Balance": "현재의 균형", "Current Balance": "현재의 균형",
"Current Balances": "현재 잔액", "Current Balances": "현재 잔액",
"Current Business Date": "현재 영업일", "Current Business Date": "현재 영업일",
+4
View File
@@ -1579,6 +1579,10 @@
"Currency Name": "Valiutos pavadinimas", "Currency Name": "Valiutos pavadinimas",
"Currency in multiples of": "Valiuta kartotiniais", "Currency in multiples of": "Valiuta kartotiniais",
"Set the multiples of the loan and its installment": "Nustatyti paskolos ir jos įmokos kartotinius", "Set the multiples of the loan and its installment": "Nustatyti paskolos ir jos įmokos kartotinius",
"Set the saving installment in multiples of": "Nustatyti taupymo įmoką kartotiniais",
"Set the share installment in multiples of": "Nustatyti akcijų įmoką kartotiniais",
"Set the fixed deposit installment in multiples of": "Nustatyti terminuoto indėlio įmoką kartotiniais",
"Set the recurring deposit installment in multiples of": "Nustatyti pasikartojantį indėlį kartotiniais",
"Current Balance": "Dabartinis balansas", "Current Balance": "Dabartinis balansas",
"Current Balances": "Dabartiniai likučiai", "Current Balances": "Dabartiniai likučiai",
"Current Business Date": "Dabartinė verslo data", "Current Business Date": "Dabartinė verslo data",
+4
View File
@@ -1581,6 +1581,10 @@
"Currency Name": "Valūtas nosaukums", "Currency Name": "Valūtas nosaukums",
"Currency in multiples of": "Valūta daudzkārtnēs", "Currency in multiples of": "Valūta daudzkārtnēs",
"Set the multiples of the loan and its installment": "Iestatīt aizdevuma un tā maksājuma daudzkārtņus", "Set the multiples of the loan and its installment": "Iestatīt aizdevuma un tā maksājuma daudzkārtņus",
"Set the saving installment in multiples of": "Iestatīt ietaupījuma maksājumu daudzkārtņos",
"Set the share installment in multiples of": "Iestatīt akciju maksājumu daudzkārtņos",
"Set the fixed deposit installment in multiples of": "Iestatīt termiņnoguldījuma maksājumu daudzkārtņos",
"Set the recurring deposit installment in multiples of": "Iestatīt atkārtotā depozīta maksājumu daudzkārtņos",
"Current Balance": "Pašreizējā bilance", "Current Balance": "Pašreizējā bilance",
"Current Balances": "Pašreizējie atlikumi", "Current Balances": "Pašreizējie atlikumi",
"Current Business Date": "Pašreizējais darba datums", "Current Business Date": "Pašreizējais darba datums",
+4
View File
@@ -1579,6 +1579,10 @@
"Currency Name": "मुद्रा नाम", "Currency Name": "मुद्रा नाम",
"Currency in multiples of": "को गुणनमा मुद्रा", "Currency in multiples of": "को गुणनमा मुद्रा",
"Set the multiples of the loan and its installment": "ऋण र यसको किस्ताको गुणन सेट गर्नुहोस्", "Set the multiples of the loan and its installment": "ऋण र यसको किस्ताको गुणन सेट गर्नुहोस्",
"Set the saving installment in multiples of": "बचत किस्ता गुणनमा सेट गर्नुहोस्",
"Set the share installment in multiples of": "शेयर किस्ता गुणनमा सेट गर्नुहोस्",
"Set the fixed deposit installment in multiples of": "निश्चित निक्षेप किस्ता गुणनमा सेट गर्नुहोस्",
"Set the recurring deposit installment in multiples of": "आवर्ती निक्षेप किस्ता गुणनमा सेट गर्नुहोस्",
"Current Balance": "हालको मौज्दात", "Current Balance": "हालको मौज्दात",
"Current Balances": "हालको ब्यालेन्स", "Current Balances": "हालको ब्यालेन्स",
"Current Business Date": "हालको व्यापार मिति", "Current Business Date": "हालको व्यापार मिति",
+4
View File
@@ -1580,6 +1580,10 @@
"Currency Name": "Nome da moeda", "Currency Name": "Nome da moeda",
"Currency in multiples of": "Moeda em múltiplos de", "Currency in multiples of": "Moeda em múltiplos de",
"Set the multiples of the loan and its installment": "Definir os múltiplos do empréstimo e sua prestação", "Set the multiples of the loan and its installment": "Definir os múltiplos do empréstimo e sua prestação",
"Set the saving installment in multiples of": "Definir a prestação de poupança em múltiplos de",
"Set the share installment in multiples of": "Definir a prestação de ações em múltiplos de",
"Set the fixed deposit installment in multiples of": "Definir a prestação de depósito fixo em múltiplos de",
"Set the recurring deposit installment in multiples of": "Definir a prestação de depósito recorrente em múltiplos de",
"Current Balance": "Saldo Atual", "Current Balance": "Saldo Atual",
"Current Balances": "Saldos Atuais", "Current Balances": "Saldos Atuais",
"Current Business Date": "Data comercial atual", "Current Business Date": "Data comercial atual",
+4
View File
@@ -1577,6 +1577,10 @@
"Currency Name": "Jina la Sarafu", "Currency Name": "Jina la Sarafu",
"Currency in multiples of": "Sarafu katika mafungu ya", "Currency in multiples of": "Sarafu katika mafungu ya",
"Set the multiples of the loan and its installment": "Weka mafungu ya mkopo na awamu yake", "Set the multiples of the loan and its installment": "Weka mafungu ya mkopo na awamu yake",
"Set the saving installment in multiples of": "Weka awamu ya akiba katika mafungu ya",
"Set the share installment in multiples of": "Weka awamu ya hisa katika mafungu ya",
"Set the fixed deposit installment in multiples of": "Weka awamu ya amana isiyobadilika katika mafungu ya",
"Set the recurring deposit installment in multiples of": "Weka awamu ya amana inayorudiwa katika mafungu ya",
"Current Balance": "Salio la Sasa", "Current Balance": "Salio la Sasa",
"Current Balances": "Mizani ya Sasa", "Current Balances": "Mizani ya Sasa",
"Current Business Date": "Tarehe ya Biashara ya Sasa", "Current Business Date": "Tarehe ya Biashara ya Sasa",