Skip to content

Commit 9cde07c

Browse files
author
Jose Alberto Hernandez
committed
Loan Product Capitalized Income tab for Adv Pment Alloc
1 parent ff153bb commit 9cde07c

31 files changed

+389
-23
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.html

+7-5
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,6 @@ <h4 fxFlex="98%" class="mat-h4">{{ 'labels.inputs.Loan Schedule' | translate }}<
290290
<input type="number" matInput formControlName="fixedEmiAmount" />
291291
</mat-form-field>
292292

293-
<mat-form-field fxFlex="48%">
294-
<mat-label>{{ 'labels.inputs.Balloon Repayment Amount' | translate }}</mat-label>
295-
<input type="number" matInput formControlName="balloonRepaymentAmount" />
296-
</mat-form-field>
297-
298293
<h4 fxFlex="98%" class="mat-h4">{{ 'labels.heading.Interest Calculations' | translate }}</h4>
299294

300295
<mat-form-field fxFlex="48%">
@@ -474,6 +469,13 @@ <h4 fxFlex="98%" class="mat-h4">
474469
<span fxFlex="60%">{{ loansAccountTermsData.interestRecalculationData.recalculationRestFrequencyInterval }}</span>
475470
</div>
476471

472+
<div fxFlexFill>
473+
<span fxFlex="40%"
474+
><b>{{ 'labels.inputs.Enable income capitalization' | translate }}</b></span
475+
>
476+
<span fxFlex="60%">{{ enableIncomeCapitalization | yesNo }}</span>
477+
</div>
478+
477479
<ng-container *ngIf="multiDisburseLoan">
478480
<mat-divider fxFlex="98%"></mat-divider>
479481
<div fxFlexFill *ngIf="allowAddDisbursementDetails()">

src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.ts

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
100100
currency: Currency;
101101

102102
productEnableDownPayment = false;
103+
enableIncomeCapitalization = false;
103104
isProgressive = false;
104105

105106
/**
@@ -128,6 +129,7 @@ export class LoansAccountTermsStepComponent implements OnInit, OnChanges {
128129
this.loansAccountTermsData = this.loansAccountTemplate;
129130
}
130131
this.productEnableDownPayment = this.loansAccountTermsData.product.enableDownPayment;
132+
this.enableIncomeCapitalization = this.loansAccountTermsData.product.enableIncomeCapitalization;
131133
this.isProgressive =
132134
this.loansAccountTermsData.loanScheduleType.code == LoanProducts.LOAN_SCHEDULE_TYPE_PROGRESSIVE;
133135
if (this.loansAccountTermsData.product) {

src/app/loans/loans-view/account-details/account-details.component.html

+15
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,21 @@ <h3>{{ 'labels.heading.Loan Details' | translate }}</h3>
7979
<span fxFlex="50%">{{ loanDetails.chargeOffBehaviour.value | translateKey: 'catalogs' }}</span>
8080
</div>
8181

82+
<div fxFlexFill>
83+
<span fxFlex="50%"> {{ 'labels.inputs.Enable income capitalization' | translate }}</span>
84+
<span fxFlex="50%"> {{ loanDetails.enableAutoRepaymentForDownPayment | yesNo }} </span>
85+
</div>
86+
87+
<div fxFlexFill *ngIf="loanDetails.enableAutoRepaymentForDownPayment">
88+
<span fxFlex="50%"> {{ 'labels.inputs.Income capitalization calculation type' | translate }}</span>
89+
<span fxFlex="50%"> {{ loanDetails.capitalizedIncomeCalculationType?.value | translateKey: 'catalogs' }} </span>
90+
</div>
91+
92+
<div fxFlexFill *ngIf="loanDetails.enableAutoRepaymentForDownPayment">
93+
<span fxFlex="50%"> {{ 'labels.inputs.Income capitalization strategy' | translate }}</span>
94+
<span fxFlex="50%"> {{ loanDetails.capitalizedIncomeStrategy?.value | translateKey: 'catalogs' }} </span>
95+
</div>
96+
8297
<div fxFlexFill>
8398
<span fxFlex="50%"> {{ 'labels.inputs.Grace: On Principal Payment' | translate }}</span>
8499
<span fxFlex="50%"> {{ loanDetails.graceOnPrincipalPayment }} </span>

src/app/products/loan-products/common/loan-product-summary/loan-product-summary.component.html

+21
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,27 @@ <h3 class="mat-h3" fxFlexFill>{{ 'labels.inputs.Overdue Charges' | translate }}<
859859
</table>
860860
</div>
861861

862+
<div fxFlexFill *ngIf="isAdvancedAccountingEnabled()" fxLayout="row wrap" fxLayout.lt-md="column">
863+
<h3 class="mat-h3" fxFlexFill>{{ 'labels.inputs.Income capitalization' | translate }}</h3>
864+
865+
<mat-divider [inset]="true"></mat-divider>
866+
867+
<div fxFlexFill>
868+
<span fxFlex="47%">{{ 'labels.inputs.Enable income capitalization' | translate }}:</span>
869+
<span fxFlex="53%">{{ loanProduct.enableIncomeCapitalization | yesNo }}</span>
870+
</div>
871+
872+
<div fxFlexFill *ngIf="loanProduct.enableIncomeCapitalization">
873+
<span fxFlex="47%">{{ 'labels.inputs.Income capitalization calculation type' | translate }}:</span>
874+
<span fxFlex="53%">{{ loanProduct.capitalizedIncomeCalculationType?.value | translateKey: 'catalogs' }}</span>
875+
</div>
876+
877+
<div fxFlexFill *ngIf="loanProduct.enableIncomeCapitalization">
878+
<span fxFlex="47%">{{ 'labels.inputs.Income capitalization strategy' | translate }}:</span>
879+
<span fxFlex="53%">{{ loanProduct.capitalizedIncomeStrategy?.value | translateKey: 'catalogs' }}</span>
880+
</div>
881+
</div>
882+
862883
<h3 class="mat-h3" fxFlexFill>{{ 'labels.heading.Accounting' | translate }}</h3>
863884

864885
<mat-divider [inset]="true"></mat-divider>

src/app/products/loan-products/common/loan-product-summary/loan-product-summary.component.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,25 @@ export class LoanProductSummaryComponent implements OnInit, OnChanges {
275275
this.loanProductsTemplate.daysInYearTypeOptions
276276
);
277277
this.loanProduct.daysInYearType = optionValue;
278-
if (this.isAdvancedPaymentAllocation && this.loanProduct.daysInYearType.id == 1) {
278+
if (this.isAdvancedPaymentAllocation && this.loanProduct.daysInYearType?.id == 1) {
279279
optionValue = this.optionDataLookUp(
280280
this.loanProduct.daysInYearCustomStrategy,
281281
this.loanProductsTemplate.daysInYearCustomStrategyOptions
282282
);
283283
}
284284
this.loanProduct.daysInYearCustomStrategy = optionValue;
285+
if (this.isAdvancedPaymentAllocation && this.loanProduct.enableIncomeCapitalization) {
286+
optionValue = this.optionDataLookUp(
287+
this.loanProduct.capitalizedIncomeCalculationType,
288+
this.loanProductsTemplate.capitalizedIncomeCalculationTypeOptions
289+
);
290+
this.loanProduct.capitalizedIncomeCalculationType = optionValue;
291+
optionValue = this.optionDataLookUp(
292+
this.loanProduct.capitalizedIncomeStrategy,
293+
this.loanProductsTemplate.capitalizedIncomeStrategyOptions
294+
);
295+
this.loanProduct.capitalizedIncomeStrategy = optionValue;
296+
}
285297
optionValue = this.optionDataLookUp(
286298
this.loanProduct.interestRateFrequencyType,
287299
this.loanProductsTemplate.interestRateFrequencyTypeOptions

src/app/products/loan-products/create-loan-product/create-loan-product.component.html

+14
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,20 @@
9191
</mifosx-loan-product-charges-step>
9292
</mat-step>
9393

94+
<mat-step *ngIf="isAdvancedPaymentStrategy" [stepControl]="loanIncomeCapitalizationForm" completed>
95+
<ng-template matStepLabel>{{ 'labels.inputs.INCOME CAPITALIZATION' | translate }}</ng-template>
96+
97+
<mifosx-loan-product-capitalized-income-step
98+
[capitalizedIncome]="capitalizedIncome"
99+
[capitalizedIncomeCalculationTypeOptions]="loanProductsTemplate.capitalizedIncomeCalculationTypeOptions"
100+
[capitalizedIncomeStrategyOptions]="loanProductsTemplate.capitalizedIncomeStrategyOptions"
101+
(setCapitalizedIncome)="setCapitalizedIncome($event)"
102+
>
103+
</mifosx-loan-product-capitalized-income-step>
104+
105+
<mifosx-stepper-buttons></mifosx-stepper-buttons>
106+
</mat-step>
107+
94108
<mat-step [stepControl]="loanProductAccountingForm">
95109
<ng-template matStepLabel>{{ 'labels.inputs.ACCOUNTING' | translate }}</ng-template>
96110

src/app/products/loan-products/create-loan-product/create-loan-product.component.ts

+25
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ import { LoanProducts } from '../loan-products';
1717
import {
1818
AdvancedPaymentAllocation,
1919
AdvancedPaymentStrategy,
20+
CapitalizedIncome,
2021
PaymentAllocation
2122
} from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
2223
import { Accounting } from 'app/core/utils/accounting';
2324
import { StringEnumOptionData } from '../../../shared/models/option-data.model';
25+
import { LoanProductCapitalizedIncomeStepComponent } from '../loan-product-stepper/loan-product-capitalized-income-step/loan-product-capitalized-income-step.component';
2426

2527
@Component({
2628
selector: 'mifosx-create-loan-product',
@@ -33,6 +35,8 @@ export class CreateLoanProductComponent implements OnInit {
3335
loanProductCurrencyStep: LoanProductCurrencyStepComponent;
3436
@ViewChild(LoanProductInterestRefundStepComponent, { static: true })
3537
loanProductInterestRefundStep: LoanProductInterestRefundStepComponent;
38+
@ViewChild(LoanProductCapitalizedIncomeStepComponent, { static: true })
39+
loanProductCapitalizedIncomeStep: LoanProductCapitalizedIncomeStepComponent;
3640
@ViewChild(LoanProductTermsStepComponent, { static: true }) loanProductTermsStep: LoanProductTermsStepComponent;
3741
@ViewChild(LoanProductSettingsStepComponent, { static: true })
3842
loanProductSettingsStep: LoanProductSettingsStepComponent;
@@ -51,6 +55,8 @@ export class CreateLoanProductComponent implements OnInit {
5155
advancedPaymentAllocations: AdvancedPaymentAllocation[] = [];
5256
advancedCreditAllocations: AdvancedPaymentAllocation[] = [];
5357

58+
capitalizedIncome: CapitalizedIncome | null = null;
59+
5460
/**
5561
* @param {ActivatedRoute} route Activated Route.
5662
* @param {ProductsService} productsService Product Service.
@@ -105,6 +111,19 @@ export class CreateLoanProductComponent implements OnInit {
105111

106112
advancePaymentStrategy(value: string) {
107113
this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value);
114+
if (this.isAdvancedPaymentStrategy) {
115+
if (this.loanProductsTemplate.enableIncomeCapitalization) {
116+
this.capitalizedIncome = {
117+
enableIncomeCapitalization: true,
118+
incomeCapitalizationCalculationType: this.loanProductsTemplate.capitalizedIncomeCalculationTypeOptions[0],
119+
incomeCapitalizationStrategy: this.loanProductsTemplate.capitalizedIncomeStrategyOptions[0]
120+
};
121+
} else {
122+
this.capitalizedIncome = {
123+
enableIncomeCapitalization: false
124+
};
125+
}
126+
}
108127
}
109128

110129
buildAdvancedPaymentAllocation(): void {
@@ -133,6 +152,12 @@ export class CreateLoanProductComponent implements OnInit {
133152
return this.loanProductAccountingStep.loanProductAccountingForm;
134153
}
135154

155+
get loanIncomeCapitalizationForm() {
156+
if (this.loanProductCapitalizedIncomeStep != null) {
157+
return this.loanProductCapitalizedIncomeStep.loanIncomeCapitalizationForm;
158+
}
159+
}
160+
136161
get loanProductFormValid() {
137162
return (
138163
this.loanProductDetailsForm.valid &&

src/app/products/loan-products/edit-loan-product/edit-loan-product.component.html

+16
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
(supportedInterestRefundTypes)="setSupportedInterestRefundTypes($event)"
5555
>
5656
</mifosx-loan-product-interest-refund-step>
57+
58+
<mifosx-stepper-buttons></mifosx-stepper-buttons>
5759
</mat-step>
5860

5961
<mat-step *ngIf="isAdvancedPaymentStrategy" completed>
@@ -91,6 +93,20 @@
9193
</mifosx-loan-product-charges-step>
9294
</mat-step>
9395

96+
<mat-step *ngIf="isAdvancedPaymentStrategy" [stepControl]="loanIncomeCapitalizationForm" completed>
97+
<ng-template matStepLabel>{{ 'labels.inputs.INCOME CAPITALIZATION' | translate }}</ng-template>
98+
99+
<mifosx-loan-product-capitalized-income-step
100+
[capitalizedIncome]="capitalizedIncome"
101+
[capitalizedIncomeCalculationTypeOptions]="loanProductAndTemplate.capitalizedIncomeCalculationTypeOptions"
102+
[capitalizedIncomeStrategyOptions]="loanProductAndTemplate.capitalizedIncomeStrategyOptions"
103+
(setCapitalizedIncome)="setCapitalizedIncome($event)"
104+
>
105+
</mifosx-loan-product-capitalized-income-step>
106+
107+
<mifosx-stepper-buttons></mifosx-stepper-buttons>
108+
</mat-step>
109+
94110
<mat-step [stepControl]="loanProductAccountingForm" completed>
95111
<ng-template matStepLabel>{{ 'labels.inputs.ACCOUNTING' | translate }}</ng-template>
96112

src/app/products/loan-products/edit-loan-product/edit-loan-product.component.ts

+36
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ import {
1818
AdvancedCreditAllocation,
1919
AdvancedPaymentAllocation,
2020
AdvancedPaymentStrategy,
21+
CapitalizedIncome,
2122
CreditAllocation,
2223
PaymentAllocation
2324
} from '../loan-product-stepper/loan-product-payment-strategy-step/payment-allocation-model';
2425
import { Accounting } from 'app/core/utils/accounting';
2526
import { LoanProductInterestRefundStepComponent } from '../loan-product-stepper/loan-product-interest-refund-step/loan-product-interest-refund-step.component';
2627
import { StringEnumOptionData } from '../../../shared/models/option-data.model';
28+
import { LoanProductCapitalizedIncomeStepComponent } from '../loan-product-stepper/loan-product-capitalized-income-step/loan-product-capitalized-income-step.component';
2729

2830
@Component({
2931
selector: 'mifosx-edit-loan-product',
@@ -36,6 +38,8 @@ export class EditLoanProductComponent implements OnInit {
3638
loanProductCurrencyStep: LoanProductCurrencyStepComponent;
3739
@ViewChild(LoanProductInterestRefundStepComponent, { static: true })
3840
loanProductInterestRefundStep: LoanProductInterestRefundStepComponent;
41+
@ViewChild(LoanProductCapitalizedIncomeStepComponent, { static: true })
42+
loanProductCapitalizedIncomeStep: LoanProductCapitalizedIncomeStepComponent;
3943
@ViewChild(LoanProductTermsStepComponent, { static: true }) loanProductTermsStep: LoanProductTermsStepComponent;
4044
@ViewChild(LoanProductSettingsStepComponent, { static: true })
4145
loanProductSettingsStep: LoanProductSettingsStepComponent;
@@ -55,6 +59,8 @@ export class EditLoanProductComponent implements OnInit {
5559
advancedCreditAllocations: AdvancedCreditAllocation[] = [];
5660
supportedInterestRefundTypes: StringEnumOptionData[] = [];
5761

62+
capitalizedIncome: CapitalizedIncome | null = null;
63+
5864
/**
5965
* @param {ActivatedRoute} route Activated Route.
6066
* @param {ProductsService} productsService Product Service.
@@ -90,6 +96,17 @@ export class EditLoanProductComponent implements OnInit {
9096
this.paymentAllocation = this.loanProductAndTemplate.paymentAllocation;
9197
this.creditAllocation = this.loanProductAndTemplate.creditAllocation;
9298
this.supportedInterestRefundTypes = this.loanProductAndTemplate.supportedInterestRefundTypes;
99+
if (this.loanProductAndTemplate.enableIncomeCapitalization) {
100+
this.capitalizedIncome = {
101+
enableIncomeCapitalization: true,
102+
incomeCapitalizationCalculationType: this.loanProductAndTemplate.capitalizedIncomeCalculationType.id,
103+
incomeCapitalizationStrategy: this.loanProductAndTemplate.capitalizedIncomeStrategy.id
104+
};
105+
} else {
106+
this.capitalizedIncome = {
107+
enableIncomeCapitalization: false
108+
};
109+
}
93110
}
94111
}
95112

@@ -115,6 +132,12 @@ export class EditLoanProductComponent implements OnInit {
115132
}
116133
}
117134

135+
get loanIncomeCapitalizationForm() {
136+
if (this.loanProductCapitalizedIncomeStep != null) {
137+
return this.loanProductCapitalizedIncomeStep.loanIncomeCapitalizationForm;
138+
}
139+
}
140+
118141
advancePaymentStrategy(value: string): void {
119142
this.isAdvancedPaymentStrategy = LoanProducts.isAdvancedPaymentAllocationStrategy(value);
120143
}
@@ -146,6 +169,12 @@ export class EditLoanProductComponent implements OnInit {
146169
this.wasPaymentAllocationChanged = value;
147170
}
148171

172+
setCapitalizedIncome(capitalizedIncome: CapitalizedIncome): void {
173+
if (this.isAdvancedPaymentStrategy) {
174+
this.capitalizedIncome = capitalizedIncome;
175+
}
176+
}
177+
149178
get loanProductAccountingForm() {
150179
return this.loanProductAccountingStep.loanProductAccountingForm;
151180
}
@@ -184,6 +213,13 @@ export class EditLoanProductComponent implements OnInit {
184213
loanProduct['paymentAllocation'] = this.paymentAllocation;
185214
loanProduct['creditAllocation'] = this.creditAllocation;
186215
loanProduct['supportedInterestRefundTypes'] = this.supportedInterestRefundTypes;
216+
if (this.capitalizedIncome != null) {
217+
loanProduct['enableIncomeCapitalization'] = this.capitalizedIncome.enableIncomeCapitalization;
218+
if (this.capitalizedIncome.enableIncomeCapitalization) {
219+
loanProduct['capitalizedIncomeCalculationType'] = this.capitalizedIncome.incomeCapitalizationCalculationType;
220+
loanProduct['capitalizedIncomeStrategy'] = this.capitalizedIncome.incomeCapitalizationStrategy;
221+
}
222+
}
187223
}
188224
return loanProduct;
189225
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<form [formGroup]="loanIncomeCapitalizationForm">
2+
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
3+
<mat-checkbox fxFlex="98%" labelPosition="before" formControlName="enableIncomeCapitalization">
4+
{{ 'labels.inputs.Enable income capitalization' | translate }}
5+
</mat-checkbox>
6+
7+
<mat-form-field fxFlex="48%" *ngIf="enableIncomeCapitalization">
8+
<mat-label>{{ 'labels.inputs.Income capitalization calculation type' | translate }}</mat-label>
9+
<mat-select formControlName="incomeCapitalizationCalculationType" required>
10+
<mat-option
11+
*ngFor="let capitalizedIncomeCalculationType of capitalizedIncomeCalculationTypeOptions"
12+
[value]="capitalizedIncomeCalculationType.id"
13+
>
14+
{{ capitalizedIncomeCalculationType.value | translateKey: 'catalogs' }}
15+
</mat-option>
16+
</mat-select>
17+
</mat-form-field>
18+
<mat-form-field fxFlex="48%" *ngIf="enableIncomeCapitalization">
19+
<mat-label>{{ 'labels.inputs.Income capitalization strategy' | translate }}</mat-label>
20+
<mat-select formControlName="incomeCapitalizationStrategy" required>
21+
<mat-option
22+
*ngFor="let capitalizedIncomeStrategy of capitalizedIncomeStrategyOptions"
23+
[value]="capitalizedIncomeStrategy.id"
24+
>
25+
{{ capitalizedIncomeStrategy.value | translateKey: 'catalogs' }}
26+
</mat-option>
27+
</mat-select>
28+
</mat-form-field>
29+
</div>
30+
</form>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.margin-t {
2+
margin-top: 1em;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { LoanProductCapitalizedIncomeStepComponent } from './loan-product-capitalsed-income-step.component';
4+
5+
describe('LoanProductCapitalizedIncomeStepComponent', () => {
6+
let component: LoanProductCapitalizedIncomeStepComponent;
7+
let fixture: ComponentFixture<LoanProductCapitalizedIncomeStepComponent>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
declarations: [LoanProductCapitalizedIncomeStepComponent]
12+
}).compileComponents();
13+
14+
fixture = TestBed.createComponent(LoanProductCapitalizedIncomeStepComponent);
15+
component = fixture.componentInstance;
16+
fixture.detectChanges();
17+
});
18+
19+
it('should create', () => {
20+
expect(component).toBeTruthy();
21+
});
22+
});

0 commit comments

Comments
 (0)