Merging Alberto changes in main (#2406)

* Loan Product Capitalized Income tab for Adv Pment Alloc

* fix: Loan Product Capitalized Income values

---------

Co-authored-by: Jose Alberto Hernandez <alberto@black-box.local>
Co-authored-by: Jose Alberto Hernandez <alberto@art3ch.solutions>
This commit is contained in:
Felix van Hove
2025-04-16 11:17:03 -06:00
committed by GitHub
co-authored by Jose Alberto Hernandez Jose Alberto Hernandez
parent 8d2df1e2ed
commit 82e776eebe
31 changed files with 425 additions and 23 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mifosx-web-app",
"version": "0.10.0",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mifosx-web-app",
"version": "0.10.0",
"version": "1.0.0",
"hasInstallScript": true,
"license": "MPL-2.0",
"dependencies": {
@@ -290,11 +290,6 @@
<input type="number" matInput formControlName="fixedEmiAmount" />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Balloon Repayment Amount' | translate }}</mat-label>
<input type="number" matInput formControlName="balloonRepaymentAmount" />
</mat-form-field>
<h4 fxFlex="98%" class="mat-h4">{{ 'labels.heading.Interest Calculations' | translate }}</h4>
<mat-form-field fxFlex="48%">
@@ -474,6 +469,13 @@
<span fxFlex="60%">{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyInterval }}</span>
</div>
<div fxFlexFill>
<span fxFlex="40%"
><b>{{ 'labels.inputs.Enable income capitalization' | translate }}</b></span
>
<span fxFlex="60%">{{ enableIncomeCapitalization | yesNo }}</span>
</div>
<ng-container *ngIf="multiDisburseLoan">
<mat-divider fxFlex="98%"></mat-divider>
<div fxFlexFill *ngIf="allowAddDisbursementDetails()">
@@ -100,6 +100,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
currency: Currency;
productEnableDownPayment = false;
enableIncomeCapitalization = false;
isProgressive = false;
/**
@@ -128,6 +129,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
this.loansAccountTermsData = this.loansAccountTemplate;
}
this.productEnableDownPayment = this.loansAccountTermsData.product.enableDownPayment;
this.enableIncomeCapitalization = this.loansAccountTermsData.product.enableIncomeCapitalization;
this.isProgressive =
this.loansAccountTermsData.loanScheduleType.code == LoanProducts.LOAN_SCHEDULE_TYPE_PROGRESSIVE;
if (this.loansAccountTermsData.product) {
@@ -79,6 +79,21 @@
<span fxFlex="50%">{{ loanDetails.chargeOffBehaviour.value | translateKey: 'catalogs' }}</span>
</div>
<div fxFlexFill>
<span fxFlex="50%"> {{ 'labels.inputs.Enable income capitalization' | translate }}</span>
<span fxFlex="50%"> {{ loanDetails.enableIncomeCapitalization | yesNo }} </span>
</div>
<div fxFlexFill *ngIf="loanDetails.enableIncomeCapitalization">
<span fxFlex="50%"> {{ 'labels.inputs.Income capitalization calculation type' | translate }}</span>
<span fxFlex="50%"> {{ loanDetails.capitalizedIncomeCalculationType?.value | translateKey: 'catalogs' }} </span>
</div>
<div fxFlexFill *ngIf="loanDetails.enableIncomeCapitalization">
<span fxFlex="50%"> {{ 'labels.inputs.Income capitalization strategy' | translate }}</span>
<span fxFlex="50%"> {{ loanDetails.capitalizedIncomeStrategy?.value | translateKey: 'catalogs' }} </span>
</div>
<div fxFlexFill>
<span fxFlex="50%"> {{ 'labels.inputs.Grace: On Principal Payment' | translate }}</span>
<span fxFlex="50%"> {{ loanDetails.graceOnPrincipalPayment }} </span>
@@ -859,6 +859,27 @@
</table>
</div>
<div fxFlexFill *ngIf="isAdvancedPaymentAllocation" fxLayout="row wrap" fxLayout.lt-md="column">
<h3 class="mat-h3" fxFlexFill>{{ 'labels.inputs.Income capitalization' | translate }}</h3>
<mat-divider [inset]="true"></mat-divider>
<div fxFlexFill>
<span fxFlex="47%">{{ 'labels.inputs.Enable income capitalization' | translate }}:</span>
<span fxFlex="53%">{{ loanProduct.enableIncomeCapitalization | yesNo }}</span>
</div>
<div fxFlexFill *ngIf="loanProduct.enableIncomeCapitalization">
<span fxFlex="47%">{{ 'labels.inputs.Income capitalization calculation type' | translate }}:</span>
<span fxFlex="53%">{{ loanProduct.capitalizedIncomeCalculationType?.value | translateKey: 'catalogs' }}</span>
</div>
<div fxFlexFill *ngIf="loanProduct.enableIncomeCapitalization">
<span fxFlex="47%">{{ 'labels.inputs.Income capitalization strategy' | translate }}:</span>
<span fxFlex="53%">{{ loanProduct.capitalizedIncomeStrategy?.value | translateKey: 'catalogs' }}</span>
</div>
</div>
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Accounting' | translate }}</h3>
<mat-divider [inset]="true"></mat-divider>
@@ -275,13 +275,25 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
this.loanProductsTemplate.daysInYearTypeOptions
);
this.loanProduct.daysInYearType = optionValue;
if (this.isAdvancedPaymentAllocation && this.loanProduct.daysInYearType.id == 1) {
if (this.isAdvancedPaymentAllocation && this.loanProduct.daysInYearType?.id == 1) {
optionValue = this.optionDataLookUp(
this.loanProduct.daysInYearCustomStrategy,
this.loanProductsTemplate.daysInYearCustomStrategyOptions
);
}
this.loanProduct.daysInYearCustomStrategy = optionValue;
if (this.isAdvancedPaymentAllocation && this.loanProduct.enableIncomeCapitalization) {
optionValue = this.optionDataLookUp(
this.loanProduct.capitalizedIncomeCalculationType,
this.loanProductsTemplate.capitalizedIncomeCalculationTypeOptions
);
this.loanProduct.capitalizedIncomeCalculationType = optionValue;
optionValue = this.optionDataLookUp(
this.loanProduct.capitalizedIncomeStrategy,
this.loanProductsTemplate.capitalizedIncomeStrategyOptions
);
this.loanProduct.capitalizedIncomeStrategy = optionValue;
}
optionValue = this.optionDataLookUp(
this.loanProduct.interestRateFrequencyType,
this.loanProductsTemplate.interestRateFrequencyTypeOptions
@@ -91,6 +91,20 @@
</mifosx-loan-product-charges-step>
</mat-step>
<mat-step *ngIf="isAdvancedPaymentStrategy" [stepControl]="loanIncomeCapitalizationForm" completed>
<ng-template matStepLabel>{{ 'labels.inputs.INCOME CAPITALIZATION' | translate }}</ng-template>
<mifosx-loan-product-capitalized-income-step
[capitalizedIncome]="capitalizedIncome"
[capitalizedIncomeCalculationTypeOptions]="loanProductsTemplate.capitalizedIncomeCalculationTypeOptions"
[capitalizedIncomeStrategyOptions]="loanProductsTemplate.capitalizedIncomeStrategyOptions"
(setCapitalizedIncome)="setCapitalizedIncome($event)"
>
</mifosx-loan-product-capitalized-income-step>
<mifosx-stepper-buttons></mifosx-stepper-buttons>
</mat-step>
<mat-step [stepControl]="loanProductAccountingForm">
<ng-template matStepLabel>{{ 'labels.inputs.ACCOUNTING' | translate }}</ng-template>
@@ -17,10 +17,12 @@ import { LoanProducts } from '../loan-products';
import {
AdvancedPaymentAllocation,
AdvancedPaymentStrategy,
CapitalizedIncome,
PaymentAllocation
} from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { Accounting } from 'app/core/utils/accounting';
import { StringEnumOptionData } from '../../../shared/models/option-data.model';
import { LoanProductCapitalizedIncomeStepComponent } from '../loan-product-stepper/loan-product-capitalized-income-step/loan-product-capitalized-income-step.component';
@Component({
selector: 'mifosx-create-loan-product',
@@ -33,6 +35,8 @@ export class CreateLoanProductComponent implements OnInit {
loanProductCurrencyStep: LoanProductCurrencyStepComponent;
@ViewChild(LoanProductInterestRefundStepComponent, { static: true })
loanProductInterestRefundStep: LoanProductInterestRefundStepComponent;
@ViewChild(LoanProductCapitalizedIncomeStepComponent, { static: true })
loanProductCapitalizedIncomeStep: LoanProductCapitalizedIncomeStepComponent;
@ViewChild(LoanProductTermsStepComponent, { static: true }) loanProductTermsStep: LoanProductTermsStepComponent;
@ViewChild(LoanProductSettingsStepComponent, { static: true })
loanProductSettingsStep: LoanProductSettingsStepComponent;
@@ -51,6 +55,8 @@ export class CreateLoanProductComponent implements OnInit {
advancedPaymentAllocations: AdvancedPaymentAllocation[] = [];
advancedCreditAllocations: AdvancedPaymentAllocation[] = [];
capitalizedIncome: CapitalizedIncome | null = null;
/**
* @param {ActivatedRoute} route Activated Route.
* @param {ProductsService} productsService Product Service.
@@ -105,6 +111,19 @@ export class CreateLoanProductComponent implements OnInit {
advancePaymentStrategy(value: string) {
this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value);
if (this.isAdvancedPaymentStrategy) {
if (this.loanProductsTemplate.enableIncomeCapitalization) {
this.capitalizedIncome = {
enableIncomeCapitalization: true,
incomeCapitalizationCalculationType: this.loanProductsTemplate.capitalizedIncomeCalculationTypeOptions[0],
incomeCapitalizationStrategy: this.loanProductsTemplate.capitalizedIncomeStrategyOptions[0]
};
} else {
this.capitalizedIncome = {
enableIncomeCapitalization: false
};
}
}
}
buildAdvancedPaymentAllocation(): void {
@@ -125,6 +144,12 @@ export class CreateLoanProductComponent implements OnInit {
this.supportedInterestRefundTypes = supportedInterestRefundTypes;
}
setCapitalizedIncome(capitalizedIncome: CapitalizedIncome): void {
if (this.isAdvancedPaymentStrategy) {
this.capitalizedIncome = capitalizedIncome;
}
}
get loanProductSettingsForm() {
return this.loanProductSettingsStep.loanProductSettingsForm;
}
@@ -133,6 +158,12 @@ export class CreateLoanProductComponent implements OnInit {
return this.loanProductAccountingStep.loanProductAccountingForm;
}
get loanIncomeCapitalizationForm() {
if (this.loanProductCapitalizedIncomeStep != null) {
return this.loanProductCapitalizedIncomeStep.loanIncomeCapitalizationForm;
}
}
get loanProductFormValid() {
return (
this.loanProductDetailsForm.valid &&
@@ -156,6 +187,13 @@ export class CreateLoanProductComponent implements OnInit {
loanProduct['paymentAllocation'] = this.paymentAllocation;
loanProduct['creditAllocation'] = this.creditAllocation;
loanProduct['supportedInterestRefundTypes'] = this.supportedInterestRefundTypes;
if (this.capitalizedIncome != null) {
loanProduct['enableIncomeCapitalization'] = this.capitalizedIncome.enableIncomeCapitalization;
if (this.capitalizedIncome.enableIncomeCapitalization) {
loanProduct['capitalizedIncomeCalculationType'] = this.capitalizedIncome.incomeCapitalizationCalculationType;
loanProduct['capitalizedIncomeStrategy'] = this.capitalizedIncome.incomeCapitalizationStrategy;
}
}
}
return loanProduct;
}
@@ -54,6 +54,8 @@
(supportedInterestRefundTypes)="setSupportedInterestRefundTypes($event)"
>
</mifosx-loan-product-interest-refund-step>
<mifosx-stepper-buttons></mifosx-stepper-buttons>
</mat-step>
<mat-step *ngIf="isAdvancedPaymentStrategy" completed>
@@ -91,6 +93,20 @@
</mifosx-loan-product-charges-step>
</mat-step>
<mat-step *ngIf="isAdvancedPaymentStrategy" [stepControl]="loanIncomeCapitalizationForm" completed>
<ng-template matStepLabel>{{ 'labels.inputs.INCOME CAPITALIZATION' | translate }}</ng-template>
<mifosx-loan-product-capitalized-income-step
[capitalizedIncome]="capitalizedIncome"
[capitalizedIncomeCalculationTypeOptions]="loanProductAndTemplate.capitalizedIncomeCalculationTypeOptions"
[capitalizedIncomeStrategyOptions]="loanProductAndTemplate.capitalizedIncomeStrategyOptions"
(setCapitalizedIncome)="setCapitalizedIncome($event)"
>
</mifosx-loan-product-capitalized-income-step>
<mifosx-stepper-buttons></mifosx-stepper-buttons>
</mat-step>
<mat-step [stepControl]="loanProductAccountingForm" completed>
<ng-template matStepLabel>{{ 'labels.inputs.ACCOUNTING' | translate }}</ng-template>
@@ -18,12 +18,14 @@ import {
AdvancedCreditAllocation,
AdvancedPaymentAllocation,
AdvancedPaymentStrategy,
CapitalizedIncome,
CreditAllocation,
PaymentAllocation
} from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
import { Accounting } from 'app/core/utils/accounting';
import { LoanProductInterestRefundStepComponent } from '../loan-product-stepper/loan-product-interest-refund-step/loan-product-interest-refund-step.component';
import { StringEnumOptionData } from '../../../shared/models/option-data.model';
import { LoanProductCapitalizedIncomeStepComponent } from '../loan-product-stepper/loan-product-capitalized-income-step/loan-product-capitalized-income-step.component';
@Component({
selector: 'mifosx-edit-loan-product',
@@ -36,6 +38,8 @@ export class EditLoanProductComponent implements OnInit {
loanProductCurrencyStep: LoanProductCurrencyStepComponent;
@ViewChild(LoanProductInterestRefundStepComponent, { static: true })
loanProductInterestRefundStep: LoanProductInterestRefundStepComponent;
@ViewChild(LoanProductCapitalizedIncomeStepComponent, { static: true })
loanProductCapitalizedIncomeStep: LoanProductCapitalizedIncomeStepComponent;
@ViewChild(LoanProductTermsStepComponent, { static: true }) loanProductTermsStep: LoanProductTermsStepComponent;
@ViewChild(LoanProductSettingsStepComponent, { static: true })
loanProductSettingsStep: LoanProductSettingsStepComponent;
@@ -55,6 +59,8 @@ export class EditLoanProductComponent implements OnInit {
advancedCreditAllocations: AdvancedCreditAllocation[] = [];
supportedInterestRefundTypes: StringEnumOptionData[] = [];
capitalizedIncome: CapitalizedIncome | null = null;
/**
* @param {ActivatedRoute} route Activated Route.
* @param {ProductsService} productsService Product Service.
@@ -90,6 +96,17 @@ export class EditLoanProductComponent implements OnInit {
this.paymentAllocation = this.loanProductAndTemplate.paymentAllocation;
this.creditAllocation = this.loanProductAndTemplate.creditAllocation;
this.supportedInterestRefundTypes = this.loanProductAndTemplate.supportedInterestRefundTypes;
if (this.loanProductAndTemplate.enableIncomeCapitalization) {
this.capitalizedIncome = {
enableIncomeCapitalization: true,
incomeCapitalizationCalculationType: this.loanProductAndTemplate.capitalizedIncomeCalculationType.id,
incomeCapitalizationStrategy: this.loanProductAndTemplate.capitalizedIncomeStrategy.id
};
} else {
this.capitalizedIncome = {
enableIncomeCapitalization: false
};
}
}
}
@@ -115,6 +132,12 @@ export class EditLoanProductComponent implements OnInit {
}
}
get loanIncomeCapitalizationForm() {
if (this.loanProductCapitalizedIncomeStep != null) {
return this.loanProductCapitalizedIncomeStep.loanIncomeCapitalizationForm;
}
}
advancePaymentStrategy(value: string): void {
this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value);
}
@@ -146,6 +169,12 @@ export class EditLoanProductComponent implements OnInit {
this.wasPaymentAllocationChanged = value;
}
setCapitalizedIncome(capitalizedIncome: CapitalizedIncome): void {
if (this.isAdvancedPaymentStrategy) {
this.capitalizedIncome = capitalizedIncome;
}
}
get loanProductAccountingForm() {
return this.loanProductAccountingStep.loanProductAccountingForm;
}
@@ -184,6 +213,13 @@ export class EditLoanProductComponent implements OnInit {
loanProduct['paymentAllocation'] = this.paymentAllocation;
loanProduct['creditAllocation'] = this.creditAllocation;
loanProduct['supportedInterestRefundTypes'] = this.supportedInterestRefundTypes;
if (this.capitalizedIncome != null) {
loanProduct['enableIncomeCapitalization'] = this.capitalizedIncome.enableIncomeCapitalization;
if (this.capitalizedIncome.enableIncomeCapitalization) {
loanProduct['capitalizedIncomeCalculationType'] = this.capitalizedIncome.incomeCapitalizationCalculationType;
loanProduct['capitalizedIncomeStrategy'] = this.capitalizedIncome.incomeCapitalizationStrategy;
}
}
}
return loanProduct;
}
@@ -0,0 +1,30 @@
<form [formGroup]="loanIncomeCapitalizationForm">
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
<mat-checkbox fxFlex="98%" labelPosition="before" formControlName="enableIncomeCapitalization">
{{ 'labels.inputs.Enable income capitalization' | translate }}
</mat-checkbox>
<mat-form-field fxFlex="48%" *ngIf="enableIncomeCapitalization">
<mat-label>{{ 'labels.inputs.Income capitalization calculation type' | translate }}</mat-label>
<mat-select formControlName="incomeCapitalizationCalculationType" required>
<mat-option
*ngFor="let capitalizedIncomeCalculationType of capitalizedIncomeCalculationTypeOptions"
[value]="capitalizedIncomeCalculationType.id"
>
{{ capitalizedIncomeCalculationType.value | translateKey: 'catalogs' }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%" *ngIf="enableIncomeCapitalization">
<mat-label>{{ 'labels.inputs.Income capitalization strategy' | translate }}</mat-label>
<mat-select formControlName="incomeCapitalizationStrategy" required>
<mat-option
*ngFor="let capitalizedIncomeStrategy of capitalizedIncomeStrategyOptions"
[value]="capitalizedIncomeStrategy.id"
>
{{ capitalizedIncomeStrategy.value | translateKey: 'catalogs' }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</form>
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoanProductCapitalizedIncomeStepComponent } from './loan-product-capitalsed-income-step.component';
describe('LoanProductCapitalizedIncomeStepComponent', () => {
let component: LoanProductCapitalizedIncomeStepComponent;
let fixture: ComponentFixture<LoanProductCapitalizedIncomeStepComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [LoanProductCapitalizedIncomeStepComponent]
}).compileComponents();
fixture = TestBed.createComponent(LoanProductCapitalizedIncomeStepComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,116 @@
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { CapitalizedIncome } from '../loan-product-payment-strategy-step/payment-allocation-model';
import { StringEnumOptionData } from 'app/shared/models/option-data.model';
@Component({
selector: 'mifosx-loan-product-capitalized-income-step',
templateUrl: './loan-product-capitalized-income-step.component.html',
styleUrls: ['./loan-product-capitalized-income-step.component.scss']
})
export class LoanProductCapitalizedIncomeStepComponent implements OnChanges {
@Input() capitalizedIncome: CapitalizedIncome;
@Input() capitalizedIncomeCalculationTypeOptions: StringEnumOptionData[];
@Input() capitalizedIncomeStrategyOptions: StringEnumOptionData[];
loanIncomeCapitalizationForm: UntypedFormGroup;
enableIncomeCapitalization: boolean;
@Output() setCapitalizedIncome = new EventEmitter<CapitalizedIncome>();
constructor(private formBuilder: UntypedFormBuilder) {
this.enableIncomeCapitalization =
this.capitalizedIncome != null ? this.capitalizedIncome.enableIncomeCapitalization : false;
this.createCapitalizedIncomeForm();
this.setConditionalControls();
}
createCapitalizedIncomeForm() {
if (this.enableIncomeCapitalization) {
this.loanIncomeCapitalizationForm = this.formBuilder.group({
enableIncomeCapitalization: [this.enableIncomeCapitalization],
incomeCapitalizationCalculationType: [
this.capitalizedIncome.incomeCapitalizationCalculationType,
Validators.required
],
incomeCapitalizationStrategy: [
this.capitalizedIncome.incomeCapitalizationStrategy,
Validators.required
]
});
} else {
this.loanIncomeCapitalizationForm = this.formBuilder.group({
enableIncomeCapitalization: [this.enableIncomeCapitalization]
});
}
}
ngOnChanges(changes: SimpleChanges): void {
this.enableIncomeCapitalization = this.capitalizedIncome.enableIncomeCapitalization;
if (this.enableIncomeCapitalization) {
this.loanIncomeCapitalizationForm.patchValue({
enableIncomeCapitalization: this.enableIncomeCapitalization,
incomeCapitalizationCalculationType: this.capitalizedIncome.incomeCapitalizationCalculationType,
incomeCapitalizationStrategy: this.capitalizedIncome.incomeCapitalizationStrategy
});
}
}
setConditionalControls() {
this.loanIncomeCapitalizationForm.get('enableIncomeCapitalization').valueChanges.subscribe((enabled: boolean) => {
this.enableIncomeCapitalization = enabled;
if (this.enableIncomeCapitalization) {
const incomeCapitalizationCalculationType =
this.capitalizedIncome.incomeCapitalizationCalculationType == ''
? this.capitalizedIncomeCalculationTypeOptions[0].id
: this.capitalizedIncome.incomeCapitalizationCalculationType;
this.loanIncomeCapitalizationForm.addControl(
'incomeCapitalizationCalculationType',
new UntypedFormControl(
this.capitalizedIncome.incomeCapitalizationCalculationType ||
this.capitalizedIncomeCalculationTypeOptions[0].id,
Validators.required
)
);
const incomeCapitalizationStrategy =
this.capitalizedIncome.incomeCapitalizationStrategy == ''
? this.capitalizedIncomeStrategyOptions[0].id
: this.capitalizedIncome.incomeCapitalizationStrategy;
this.loanIncomeCapitalizationForm.addControl(
'incomeCapitalizationStrategy',
new UntypedFormControl(incomeCapitalizationStrategy, Validators.required)
);
this.setCapitalizedIncome.emit({
enableIncomeCapitalization: true,
incomeCapitalizationCalculationType: incomeCapitalizationCalculationType,
incomeCapitalizationStrategy: incomeCapitalizationStrategy
});
this.loanIncomeCapitalizationForm
.get('incomeCapitalizationCalculationType')
.valueChanges.subscribe((newValue: string) => {
this.setCapitalizedIncome.emit({
enableIncomeCapitalization: true,
incomeCapitalizationCalculationType: newValue,
incomeCapitalizationStrategy: this.loanIncomeCapitalizationForm.value.incomeCapitalizationStrategy
});
});
this.loanIncomeCapitalizationForm
.get('incomeCapitalizationStrategy')
.valueChanges.subscribe((newValue: string) => {
this.setCapitalizedIncome.emit({
enableIncomeCapitalization: true,
incomeCapitalizationCalculationType:
this.loanIncomeCapitalizationForm.value.incomeCapitalizationCalculationType,
incomeCapitalizationStrategy: newValue
});
});
} else {
this.loanIncomeCapitalizationForm.removeControl('incomeCapitalizationCalculationType');
this.loanIncomeCapitalizationForm.removeControl('incomeCapitalizationStrategy');
this.setCapitalizedIncome.emit({ enableIncomeCapitalization: false });
}
});
}
}
@@ -42,6 +42,12 @@ export interface CreditAllocation {
creditAllocationOrder: CreditAllocationOrder[];
}
export interface CapitalizedIncome {
enableIncomeCapitalization: boolean;
incomeCapitalizationCalculationType?: string;
incomeCapitalizationStrategy?: string;
}
export class PaymentAllocationTransactionTypes {
public static DEFAULT_TRANSACTION: PaymentAllocationTransactionType = { id: 1, value: 'Default', code: 'DEFAULT' };
}
@@ -715,7 +715,6 @@ export class LoanProductSettingsStepComponent implements OnInit {
if (productSettings['delinquencyBucketId'] === '') {
productSettings['delinquencyBucketId'] = null;
}
console.log(productSettings);
return productSettings;
}
@@ -66,6 +66,9 @@ export interface LoanProduct {
isArrearsBasedOnOriginalSchedule?: boolean;
isCompoundingToBePostedAsTransaction?: boolean;
recalculationRestFrequencyInterval?: number;
enableIncomeCapitalization?: boolean;
capitalizedIncomeCalculationType?: OptionData;
capitalizedIncomeStrategy?: OptionData;
canDefineInstallmentAmount: boolean;
graceOnArrearsAgeing?: number;
+3 -1
View File
@@ -121,6 +121,7 @@ import { LoanProductPaymentStrategyStepComponent } from './loan-products/loan-pr
import { ViewAdvancePaymenyAllocationComponent } from './loan-products/view-loan-product/shared/view-advance-paymeny-allocation/view-advance-paymeny-allocation.component';
import { AdvancePaymentAllocationTabComponent } from './loan-products/loan-product-stepper/loan-product-payment-strategy-step/advance-payment-allocation-tab/advance-payment-allocation-tab.component';
import { LoanProductSummaryComponent } from './loan-products/common/loan-product-summary/loan-product-summary.component';
import { LoanProductCapitalizedIncomeStepComponent } from './loan-products/loan-product-stepper/loan-product-capitalized-income-step/loan-product-capitalized-income-step.component';
/**
* Products Module
@@ -249,7 +250,8 @@ import { LoanProductSummaryComponent } from './loan-products/common/loan-product
ShareProductDatatableTabComponent,
ViewAdvancePaymenyAllocationComponent,
AdvancePaymentAllocationTabComponent,
LoanProductSummaryComponent
LoanProductSummaryComponent,
LoanProductCapitalizedIncomeStepComponent
]
})
export class ProductsModule {}
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Typ pobídky",
"Include in Customer Loan Counter": "Zahrnout do přepážky zákaznických půjček",
"Income Account": "Příjmový účet",
"Income capitalization": "Kapitalizace příjmu",
"INCOME CAPITALIZATION": "KAPITALIZACE PŘÍJMU",
"Income from Charge": "Příjem z poplatku",
"Income from ChargeOff Fees": "Příjem z poplatků za ChargeOff",
"Income from ChargeOff Interest": "Příjem z úroků ChargeOff",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Heslo nesmí obsahovat po sobě jdoucí opakující se znaky",
"Password must contain at least one special character (@$!%*?&)": "Heslo musí obsahovat alespoň jeden speciální znak (@$!%*?&)",
"Password minimun length must be": "Minimální délka hesla musí být",
"Passwords do not match": "Hesla se neshodují"
"Passwords do not match": "Hesla se neshodují",
"Enable income capitalization": "Povolit kapitalizaci příjmu",
"Income capitalization calculation type": "Typ výpočtu kapitalizace příjmu",
"Income capitalization strategy": "Strategie kapitalizace příjmu"
},
"links": {
"Community": "Společenství",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Anreiztyp",
"Include in Customer Loan Counter": "In Kundenkreditzähler einbeziehen",
"Income Account": "Einkommenskonto",
"Income capitalization": "Einkommenskapitalisierung",
"INCOME CAPITALIZATION": "EINKOMMENSKAPITALISIERUNG",
"Income from Charge": "Einnahmen aus Gebühr",
"Income from ChargeOff Fees": "Einnahmen aus ChargeOff-Gebühren",
"Income from ChargeOff Interest": "Einnahmen aus ChargeOff-Zinsen",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Das Passwort darf keine aufeinanderfolgenden, sich wiederholenden Zeichen enthalten",
"Password must contain at least one special character (@$!%*?&)": "Das Passwort muss mindestens ein Sonderzeichen enthalten (@$!%*?&)",
"Password minimun length must be": "Die Mindestlänge des Passworts muss betragen",
"Passwords do not match": "Passwörter stimmen nicht überein"
"Passwords do not match": "Passwörter stimmen nicht überein",
"Enable income capitalization": "Aktivieren Sie die Einkommenskapitalisierung",
"Income capitalization calculation type": "Berechnungsart der Einkommenskapitalisierung",
"Income capitalization strategy": "Strategie zur Ertragskapitalisierung"
},
"links": {
"Community": "Gemeinschaft",
+6 -1
View File
@@ -1699,6 +1699,8 @@
"Incentive Type": "Incentive Type",
"Include in Customer Loan Counter": "Include in Customer Loan Counter",
"Income Account": "Income Account",
"Income capitalization": "Income capitalization",
"INCOME CAPITALIZATION": "INCOME CAPITALIZATION",
"Income from Charge": "Income from Charge",
"Income from ChargeOff Fees": "Income from ChargeOff Fees",
"Income from ChargeOff Interest": "Income from ChargeOff Interest",
@@ -2463,7 +2465,10 @@
"Password must have not consecutive repeating characters": "Password must have not consecutive repeating characters",
"Password must contain at least one special character (@$!%*?&)": "Password must contain at least one special character (@$!%*?&)",
"Password minimun length must be": "Password minimun length must be",
"Passwords do not match": "Passwords do not match"
"Passwords do not match": "Passwords do not match",
"Enable income capitalization": "Enable income capitalization",
"Income capitalization calculation type": "Income capitalization calculation type",
"Income capitalization strategy": "Income capitalization strategy"
},
"links": {
"Community": "Community",
+6 -1
View File
@@ -1694,6 +1694,8 @@
"Incentive Type": "Tipo de incentivo",
"Include in Customer Loan Counter": "Incluir en el contador de Créditos al cliente",
"Income Account": "Cuenta de Ingresos",
"Income capitalization": "Capitalización de ingresos",
"INCOME CAPITALIZATION": "CAPITALIZACIÓN DE INGRESOS",
"Income from Charge": "Ingresos por cargo",
"Income from ChargeOff Fees": "Ingresos por comisiones de cancelación",
"Income from ChargeOff Interest": "Ingresos por intereses de cancelación",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "La contraseña no debe tener caracteres repetidos consecutivos.",
"Password must contain at least one special character (@$!%*?&)": "La contraseña debe contener al menos un carácter especial (@$!%*?&)",
"Password minimun length must be": "La longitud mínima de la contraseña debe ser",
"Passwords do not match": "Las contraseñas no coinciden"
"Passwords do not match": "Las contraseñas no coinciden",
"Enable income capitalization": "Habilitar capitalización de ingresos",
"Income capitalization calculation type": "Tipo de cálculo de capitalización de ingresos",
"Income capitalization strategy": "Estrategia de capitalización de ingresos"
},
"links": {
"Community": "Comunidad",
+6 -1
View File
@@ -1694,6 +1694,8 @@
"Incentive Type": "Tipo de incentivo",
"Include in Customer Loan Counter": "Incluir en el contador de Créditos al cliente",
"Income Account": "Cuenta de Ingresos",
"Income capitalization": "Capitalización de ingresos",
"INCOME CAPITALIZATION": "CAPITALIZACIÓN DE INGRESOS",
"Income from Charge": "Ingresos por cargo",
"Income from ChargeOff Fees": "Ingresos por comisiones de cancelación",
"Income from ChargeOff Interest": "Ingresos por intereses de cancelación",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "La contraseña no debe tener caracteres repetidos consecutivos.",
"Password must contain at least one special character (@$!%*?&)": "La contraseña debe contener al menos un carácter especial (@$!%*?&)",
"Password minimun length must be": "La longitud mínima de la contraseña debe ser",
"Passwords do not match": "Las contraseñas no coinciden"
"Passwords do not match": "Las contraseñas no coinciden",
"Enable income capitalization": "Habilitar capitalización de ingresos",
"Income capitalization calculation type": "Tipo de cálculo de capitalización de ingresos",
"Income capitalization strategy": "Estrategia de capitalización de ingresos"
},
"links": {
"Community": "Comunidad",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Type d'incitation",
"Include in Customer Loan Counter": "Inclure dans le compteur de prêts clients",
"Income Account": "Compte de revenu",
"Income capitalization": "Capitalisation des revenus",
"INCOME CAPITALIZATION": "CAPITALISATION DES REVENUS",
"Income from Charge": "Revenu de Charge",
"Income from ChargeOff Fees": "Revenus provenant des frais ChargeOff",
"Income from ChargeOff Interest": "Revenus des intérêts facturés",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Le mot de passe ne doit pas contenir de caractères répétitifs consécutifs",
"Password must contain at least one special character (@$!%*?&)": "Le mot de passe doit contenir au moins un caractère spécial (@$!%*?&)",
"Password minimun length must be": "La longueur minimale du mot de passe doit être",
"Passwords do not match": "Les mots de passe ne correspondent pas"
"Passwords do not match": "Les mots de passe ne correspondent pas",
"Enable income capitalization": "Activer la capitalisation des revenus",
"Income capitalization calculation type": "Type de calcul de capitalisation des revenus",
"Income capitalization strategy": "Stratégie de capitalisation des revenus"
},
"links": {
"Community": "Communauté",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Tipo di incentivo",
"Include in Customer Loan Counter": "Includi nel contatore dei prestiti al cliente",
"Income Account": "Conto dei redditi",
"Income capitalization": "Capitalizzazione del reddito",
"INCOME CAPITALIZATION": "CAPITALIZZAZIONE DEL REDDITO",
"Income from Charge": "Proventi da carica",
"Income from ChargeOff Fees": "Proventi da commissioni di addebito",
"Income from ChargeOff Interest": "Proventi da interessi di addebito",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "La password non deve contenere caratteri ripetuti consecutivi",
"Password must contain at least one special character (@$!%*?&)": "La password deve contenere almeno un carattere speciale (@$!%*?&)",
"Password minimun length must be": "La lunghezza minima della password deve essere",
"Passwords do not match": "Le password non corrispondono"
"Passwords do not match": "Le password non corrispondono",
"Enable income capitalization": "Abilita la capitalizzazione del reddito",
"Income capitalization calculation type": "Tipo di calcolo della capitalizzazione del reddito",
"Income capitalization strategy": "Strategia di capitalizzazione del reddito"
},
"links": {
"Community": "Comunità",
+6 -1
View File
@@ -1696,6 +1696,8 @@
"Incentive Type": "인센티브 유형",
"Include in Customer Loan Counter": "고객 대출 카운터에 포함",
"Income Account": "소득 계정",
"Income capitalization": "소득 자본화",
"INCOME CAPITALIZATION": "소득 자본화",
"Income from Charge": "수수료 수입",
"Income from ChargeOff Fees": "ChargeOff 수수료로 인한 소득",
"Income from ChargeOff Interest": "ChargeOff 이자 소득",
@@ -2457,7 +2459,10 @@
"Password must have not consecutive repeating characters": "비밀번호에는 연속된 반복 문자가 없어야 합니다.",
"Password must contain at least one special character (@$!%*?&)": "비밀번호에는 특수 문자가 하나 이상 포함되어야 합니다. (@$!%*?&)",
"Password minimun length must be": "비밀번호의 최소 길이는 다음과 같아야 합니다.",
"Passwords do not match": "비밀번호가 일치하지 않습니다."
"Passwords do not match": "비밀번호가 일치하지 않습니다.",
"Enable income capitalization": "소득 자본화 활성화",
"Income capitalization calculation type": "소득 자본화 계산 유형",
"Income capitalization strategy": "소득 자본화 전략"
},
"links": {
"Community": "지역 사회",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Paskatinimo tipas",
"Include in Customer Loan Counter": "Įtraukti į klientų paskolų skaitiklį",
"Income Account": "Pajamų sąskaita",
"Income capitalization": "Pajamų kapitalizacija",
"INCOME CAPITALIZATION": "PAJAMŲ KAPITALIZAVIMAS",
"Income from Charge": "Pajamos iš mokesčių",
"Income from ChargeOff Fees": "Pajamos iš ChargeOff mokesčių",
"Income from ChargeOff Interest": "Pajamos iš ChargeOff palūkanų",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Slaptažodyje neturi būti iš eilės besikartojančių simbolių",
"Password must contain at least one special character (@$!%*?&)": "Slaptažodyje turi būti bent vienas specialusis simbolis (@$!%*?&)",
"Password minimun length must be": "Minimalus slaptažodžio ilgis turi būti",
"Passwords do not match": "Slaptažodžiai nesutampa"
"Passwords do not match": "Slaptažodžiai nesutampa",
"Enable income capitalization": "Įgalinti pajamų kapitalizaciją",
"Income capitalization calculation type": "Pajamų kapitalizavimo skaičiavimo tipas",
"Income capitalization strategy": "Pajamų kapitalizavimo strategija"
},
"links": {
"Community": "bendruomenė",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Stimulēšanas veids",
"Include in Customer Loan Counter": "Iekļaut klientu aizdevumu skaitītājā",
"Income Account": "Ienākumu konts",
"Income capitalization": "Ienākumu kapitalizācija",
"INCOME CAPITALIZATION": "IENĀKUMU KAPITALIZĀCIJA",
"Income from Charge": "Ienākumi no maksas",
"Income from ChargeOff Fees": "Ienākumi no ChargeOff maksas",
"Income from ChargeOff Interest": "Ienākumi no ChargeOff procentiem",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Parolē nedrīkst būt secīgas atkārtotas rakstzīmes",
"Password must contain at least one special character (@$!%*?&)": "Parolē jāsatur vismaz viena speciālā rakstzīme (@$!%*?&)",
"Password minimun length must be": "Paroles minimālajam garumam jābūt",
"Passwords do not match": "Paroles nesakrīt"
"Passwords do not match": "Paroles nesakrīt",
"Enable income capitalization": "Iespējot ienākumu kapitalizāciju",
"Income capitalization calculation type": "Ienākumu kapitalizācijas aprēķina veids",
"Income capitalization strategy": "Ienākumu kapitalizācijas stratēģija"
},
"links": {
"Community": "kopiena",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "प्रोत्साहन प्रकार",
"Include in Customer Loan Counter": "ग्राहक ऋण काउन्टरमा समावेश गर्नुहोस्",
"Income Account": "आय खाता",
"Income capitalization": "आय पूंजीकरण",
"INCOME CAPITALIZATION": "आय पूंजीकरण",
"Income from Charge": "शुल्कबाट आम्दानी",
"Income from ChargeOff Fees": "चार्जअफ शुल्कबाट आय",
"Income from ChargeOff Interest": "चार्जअफ ब्याजबाट आम्दानी",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "पासवर्डमा लगातार दोहोरिने क्यारेक्टरहरू हुनु हुँदैन",
"Password must contain at least one special character (@$!%*?&)": "पासवर्डमा कम्तिमा एउटा विशेष वर्ण हुनुपर्छ (@$!%*?&)",
"Password minimun length must be": "पासवर्ड न्यूनतम लम्बाइ हुनुपर्छ",
"Passwords do not match": "पासवर्डहरू मेल खाँदैनन्"
"Passwords do not match": "पासवर्डहरू मेल खाँदैनन्",
"Enable income capitalization": "आय पूंजीकरण सक्षम गर्नुहोस्",
"Income capitalization calculation type": "आय पूंजीकरण गणना प्रकार",
"Income capitalization strategy": "आय पूंजीकरण रणनीति"
},
"links": {
"Community": "समुदाय",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Tipo de incentivo",
"Include in Customer Loan Counter": "Incluir no contador de empréstimos do cliente",
"Income Account": "Conta de Renda",
"Income capitalization": "Capitalização de renda",
"INCOME CAPITALIZATION": "CAPITALIZAÇÃO DE RENDA",
"Income from Charge": "Renda de cobrança",
"Income from ChargeOff Fees": "Receita de taxas de cobrança",
"Income from ChargeOff Interest": "Renda de juros cobrados",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "A senha não deve conter caracteres repetidos consecutivos",
"Password must contain at least one special character (@$!%*?&)": "A senha deve conter pelo menos um caractere especial (@$!%*?&)",
"Password minimun length must be": "O comprimento mínimo da senha deve ser",
"Passwords do not match": "As senhas não coincidem"
"Passwords do not match": "As senhas não coincidem",
"Enable income capitalization": "Habilitar capitalização de renda",
"Income capitalization calculation type": "Tipo de cálculo de capitalização de renda",
"Income capitalization strategy": "Estratégia de capitalização de renda"
},
"links": {
"Community": "Comunidade",
+6 -1
View File
@@ -1695,6 +1695,8 @@
"Incentive Type": "Aina ya motisha",
"Include in Customer Loan Counter": "Jumuisha katika Kaunta ya Mkopo kwa Wateja",
"Income Account": "Akaunti ya Mapato",
"Income capitalization": "Mtaji wa mapato",
"INCOME CAPITALIZATION": "MTAJI WA KIPATO",
"Income from Charge": "Mapato kutoka kwa Malipo",
"Income from ChargeOff Fees": "Mapato kutoka kwa Ada ya ChargeOff",
"Income from ChargeOff Interest": "Mapato kutoka kwa Riba ya ChargeOff",
@@ -2456,7 +2458,10 @@
"Password must have not consecutive repeating characters": "Nenosiri lazima lisiwe na vibambo vinavyorudiwa mfululizo",
"Password must contain at least one special character (@$!%*?&)": "Nenosiri lazima liwe na angalau herufi moja maalum (@$!%*?&)",
"Password minimun length must be": "Nenosiri la urefu wa chini lazima liwe",
"Passwords do not match": "Manenosiri hayalingani"
"Passwords do not match": "Manenosiri hayalingani",
"Enable income capitalization": "Washa mtaji wa mapato",
"Income capitalization calculation type": "Aina ya kukokotoa mtaji wa mapato",
"Income capitalization strategy": "Mkakati wa mtaji wa mapato"
},
"links": {
"Community": "Jumuiya",