Merge pull request #1582 from josehernandezfintecheandomx/enhancement/loan_account_request_repayment_schedule_part1
Add Repayment Info as part of the Loan Account request
This commit is contained in:
@@ -53,6 +53,16 @@
|
|||||||
|
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step state="repayment" *ngIf="loansAccountFormValid" completed>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>REPAYMENT SCHEDULE</ng-template>
|
||||||
|
|
||||||
|
<mifosx-loans-account-schedule-step [loansAccountTemplate]="loansAccountTemplate"
|
||||||
|
[loansAccountProductTemplate]="loansAccountProductTemplate" [loansAccount]="loansAccount">
|
||||||
|
</mifosx-loans-account-schedule-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
<mat-step state="preview" *ngIf="loansAccountFormValid" completed>
|
<mat-step state="preview" *ngIf="loansAccountFormValid" completed>
|
||||||
|
|
||||||
<ng-template matStepLabel>PREVIEW</ng-template>
|
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||||
|
|||||||
@@ -121,59 +121,10 @@ export class CreateLoansAccountComponent implements OnInit {
|
|||||||
submit() {
|
submit() {
|
||||||
const locale = this.settingsService.language.code;
|
const locale = this.settingsService.language.code;
|
||||||
const dateFormat = this.settingsService.dateFormat;
|
const dateFormat = this.settingsService.dateFormat;
|
||||||
const loansAccountData = {
|
const payload = this.loansService.buildLoanRequestPayload(this.loansAccount, this.loansAccountTemplate,
|
||||||
...this.loansAccount,
|
this.loansAccountProductTemplate.calendarOptions, locale, dateFormat);
|
||||||
charges: this.loansAccount.charges.map((charge: any) => ({
|
|
||||||
chargeId: charge.id,
|
|
||||||
amount: charge.amount,
|
|
||||||
dueDate: charge.dueDate && this.dateUtils.formatDate(charge.dueDate, dateFormat),
|
|
||||||
})),
|
|
||||||
collateral: this.loansAccount.collateral.map((collateralEle: any) => ({
|
|
||||||
clientCollateralId: collateralEle.type.collateralId,
|
|
||||||
quantity: collateralEle.value,
|
|
||||||
})),
|
|
||||||
disbursementData: this.loansAccount.disbursementData.map((item: any) => ({
|
|
||||||
expectedDisbursementDate: this.dateUtils.formatDate(item.expectedDisbursementDate, dateFormat),
|
|
||||||
principal: item.principal
|
|
||||||
})),
|
|
||||||
interestChargedFromDate: this.dateUtils.formatDate(this.loansAccount.interestChargedFromDate, dateFormat),
|
|
||||||
repaymentsStartingFromDate: this.dateUtils.formatDate(this.loansAccount.repaymentsStartingFromDate, dateFormat),
|
|
||||||
submittedOnDate: this.dateUtils.formatDate(this.loansAccount.submittedOnDate, dateFormat),
|
|
||||||
expectedDisbursementDate: this.dateUtils.formatDate(this.loansAccount.expectedDisbursementDate, dateFormat),
|
|
||||||
dateFormat,
|
|
||||||
locale,
|
|
||||||
};
|
|
||||||
if (this.loansAccountTemplate.clientId) {
|
|
||||||
loansAccountData.clientId = this.loansAccountTemplate.clientId;
|
|
||||||
loansAccountData.loanType = 'individual';
|
|
||||||
} else {
|
|
||||||
loansAccountData.groupId = this.loansAccountTemplate.group.id;
|
|
||||||
loansAccountData.loanType = 'group';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loansAccountData.syncRepaymentsWithMeeting) {
|
this.loansService.createLoansAccount(payload).subscribe((response: any) => {
|
||||||
loansAccountData.calendarId = this.loansAccountProductTemplate.calendarOptions[0].id;
|
|
||||||
delete loansAccountData.syncRepaymentsWithMeeting;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loansAccountData.recalculationRestFrequencyDate) {
|
|
||||||
loansAccountData.recalculationRestFrequencyDate = this.dateUtils.formatDate(this.loansAccount.recalculationRestFrequencyDate, dateFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loansAccountData.interestCalculationPeriodType === 0) {
|
|
||||||
loansAccountData.allowPartialPeriodInterestCalcualtion = false;
|
|
||||||
}
|
|
||||||
if (!(loansAccountData.isFloatingInterestRate === false)) {
|
|
||||||
delete loansAccountData.isFloatingInterestRate;
|
|
||||||
}
|
|
||||||
if (!(this.multiDisburseLoan)) {
|
|
||||||
delete loansAccountData.disbursementData;
|
|
||||||
}
|
|
||||||
delete loansAccountData.isValid;
|
|
||||||
loansAccountData.principal = loansAccountData.principalAmount;
|
|
||||||
delete loansAccountData.principalAmount;
|
|
||||||
|
|
||||||
this.loansService.createLoansAccount(loansAccountData).subscribe((response: any) => {
|
|
||||||
this.router.navigate(['../', response.resourceId, 'general'], { relativeTo: this.route });
|
this.router.navigate(['../', response.resourceId, 'general'], { relativeTo: this.route });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,16 @@
|
|||||||
|
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
|
<mat-step>
|
||||||
|
|
||||||
|
<ng-template matStepLabel>REPAYMENT SCHEDULE</ng-template>
|
||||||
|
|
||||||
|
<mifosx-loans-account-schedule-step [loansAccountTemplate]="loansAccountAndTemplate"
|
||||||
|
[loansAccountProductTemplate]="loansAccountProductTemplate" [loansAccount]="loansAccount">
|
||||||
|
</mifosx-loans-account-schedule-step>
|
||||||
|
|
||||||
|
</mat-step>
|
||||||
|
|
||||||
<mat-step state="preview" *ngIf="loansAccountFormValidAndNotPristine" completed>
|
<mat-step state="preview" *ngIf="loansAccountFormValidAndNotPristine" completed>
|
||||||
|
|
||||||
<ng-template matStepLabel>PREVIEW</ng-template>
|
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||||
|
|||||||
@@ -60,9 +60,11 @@ export class EditLoansAccountComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
setTemplate($event: any) {
|
setTemplate($event: any) {
|
||||||
this.loansAccountProductTemplate = $event;
|
this.loansAccountProductTemplate = $event;
|
||||||
this.loansService.getLoansCollateralTemplateResource(this.loansAccountProductTemplate.loanProductId).subscribe((response: any) => {
|
if (this.loansAccountProductTemplate.loanProductId) {
|
||||||
this.collateralOptions = response.loanCollateralOptions;
|
this.loansService.getLoansCollateralTemplateResource(this.loansAccountProductTemplate.loanProductId).subscribe((response: any) => {
|
||||||
});
|
this.collateralOptions = response.loanCollateralOptions;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get Loans Account Details Form Data */
|
/** Get Loans Account Details Form Data */
|
||||||
|
|||||||
+4
-2
@@ -14,7 +14,7 @@
|
|||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%">
|
<mat-form-field fxFlex="48%" *ngIf="loanProductSelected">
|
||||||
<mat-label>Loan officer</mat-label>
|
<mat-label>Loan officer</mat-label>
|
||||||
<mat-select formControlName="loanOfficerId">
|
<mat-select formControlName="loanOfficerId">
|
||||||
<mat-option *ngFor="let loanOfficer of loanOfficerOptions" [value]="loanOfficer.id">
|
<mat-option *ngFor="let loanOfficer of loanOfficerOptions" [value]="loanOfficer.id">
|
||||||
@@ -22,6 +22,9 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" *ngIf="loanProductSelected">
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%">
|
<mat-form-field fxFlex="48%">
|
||||||
<mat-label>Loan purpose</mat-label>
|
<mat-label>Loan purpose</mat-label>
|
||||||
@@ -84,7 +87,6 @@
|
|||||||
<mat-checkbox fxFlex="48%" formControlName="createStandingInstructionAtDisbursement">
|
<mat-checkbox fxFlex="48%" formControlName="createStandingInstructionAtDisbursement">
|
||||||
<p>Create standing instructions at disbursement</p>
|
<p>Create standing instructions at disbursement</p>
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
|||||||
+3
@@ -41,6 +41,8 @@ export class LoansAccountDetailsStepComponent implements OnInit {
|
|||||||
|
|
||||||
loanId: any = null;
|
loanId: any = null;
|
||||||
|
|
||||||
|
loanProductSelected = false;
|
||||||
|
|
||||||
/** Loans Account Template with product data */
|
/** Loans Account Template with product data */
|
||||||
@Output() loansAccountProductTemplate = new EventEmitter();
|
@Output() loansAccountProductTemplate = new EventEmitter();
|
||||||
/**
|
/**
|
||||||
@@ -106,6 +108,7 @@ export class LoansAccountDetailsStepComponent implements OnInit {
|
|||||||
this.loanPurposeOptions = response.loanPurposeOptions;
|
this.loanPurposeOptions = response.loanPurposeOptions;
|
||||||
this.fundOptions = response.fundOptions;
|
this.fundOptions = response.fundOptions;
|
||||||
this.accountLinkingOptions = response.accountLinkingOptions;
|
this.accountLinkingOptions = response.accountLinkingOptions;
|
||||||
|
this.loanProductSelected = true;
|
||||||
if (response.createStandingInstructionAtDisbursement) {
|
if (response.createStandingInstructionAtDisbursement) {
|
||||||
this.loansAccountDetailsForm.get('createStandingInstructionAtDisbursement').patchValue(response.createStandingInstructionAtDisbursement);
|
this.loansAccountDetailsForm.get('createStandingInstructionAtDisbursement').patchValue(response.createStandingInstructionAtDisbursement);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||||
|
|
||||||
|
<a mat-button (click)="showRepaymentInfo()">
|
||||||
|
Repayment Info
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<mifosx-repayment-schedule-tab fxFlex="100%" [repaymentScheduleDetails]="repaymentScheduleDetails"></mifosx-repayment-schedule-tab>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
|
<button mat-raised-button matStepperPrevious>
|
||||||
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button matStepperNext>
|
||||||
|
Next
|
||||||
|
<fa-icon icon="arrow-right"></fa-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button *ngIf="loanId" [routerLink]="['../', 'general']">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoansAccountScheduleStepComponent } from './loans-account-schedule-step.component';
|
||||||
|
|
||||||
|
describe('LoansAccountScheduleStepComponent', () => {
|
||||||
|
let component: LoansAccountScheduleStepComponent;
|
||||||
|
let fixture: ComponentFixture<LoansAccountScheduleStepComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoansAccountScheduleStepComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoansAccountScheduleStepComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { LoansService } from 'app/loans/loans.service';
|
||||||
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-loans-account-schedule-step',
|
||||||
|
templateUrl: './loans-account-schedule-step.component.html',
|
||||||
|
styleUrls: ['./loans-account-schedule-step.component.scss']
|
||||||
|
})
|
||||||
|
export class LoansAccountScheduleStepComponent implements OnInit {
|
||||||
|
|
||||||
|
/** Loans Account Template */
|
||||||
|
@Input() loansAccountTemplate: any;
|
||||||
|
/** Loans Account Product Template */
|
||||||
|
@Input() loansAccountProductTemplate: any;
|
||||||
|
/** Loans Account Data */
|
||||||
|
@Input() loansAccount: any;
|
||||||
|
|
||||||
|
showRepayment = false;
|
||||||
|
repaymentScheduleDetails: any = {periods: []};
|
||||||
|
|
||||||
|
loanId: any = null;
|
||||||
|
|
||||||
|
constructor(private loansService: LoansService,
|
||||||
|
private settingsService: SettingsService,
|
||||||
|
private route: ActivatedRoute) {
|
||||||
|
this.loanId = this.route.snapshot.params['loanId'];
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void { }
|
||||||
|
|
||||||
|
showRepaymentInfo(): void {
|
||||||
|
this.repaymentScheduleDetails = {periods: []};
|
||||||
|
this.showRepayment = !this.showRepayment;
|
||||||
|
if (this.showRepayment) {
|
||||||
|
const locale = this.settingsService.language.code;
|
||||||
|
const dateFormat = this.settingsService.dateFormat;
|
||||||
|
const payload = this.loansService.buildLoanRequestPayload(this.loansAccount, this.loansAccountTemplate,
|
||||||
|
this.loansAccountProductTemplate.calendarOptions, locale, dateFormat);
|
||||||
|
|
||||||
|
this.loansService.calculateLoanSchedule(payload).subscribe((response: any) => {
|
||||||
|
this.repaymentScheduleDetails = response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-8
@@ -163,7 +163,6 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<!-- <mat-checkbox *ngIf="interestCalculationPeriodType != 0" fxFlex="48%" -->
|
|
||||||
<mat-checkbox fxFlex="48%" formControlName="allowPartialPeriodInterestCalcualtion">
|
<mat-checkbox fxFlex="48%" formControlName="allowPartialPeriodInterestCalcualtion">
|
||||||
<p>Calculate interest for exact days in partial period</p>
|
<p>Calculate interest for exact days in partial period</p>
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
@@ -192,19 +191,20 @@
|
|||||||
|
|
||||||
<h4 fxFlex="98%" class="mat-h4">Moratorium</h4>
|
<h4 fxFlex="98%" class="mat-h4">Moratorium</h4>
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%">
|
<mat-form-field fxFlex="23%">
|
||||||
<mat-label>Grace on principal payment</mat-label>
|
<mat-label>Grace on principal payment</mat-label>
|
||||||
<input type="number" matInput formControlName="graceOnPrincipalPayment">
|
<input type="number" matInput formControlName="graceOnPrincipalPayment">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%">
|
<mat-form-field fxFlex="23%">
|
||||||
<mat-label>Grace on interest payment</mat-label>
|
<mat-label>Grace on interest payment</mat-label>
|
||||||
<input type="number" matInput formControlName="graceOnInterestPayment">
|
<input type="number" matInput formControlName="graceOnInterestPayment">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-checkbox fxFlex="23%" labelPosition="before" formControlName="graceOnArrearsAgeing" class="margin-v">
|
<mat-form-field fxFlex="48%">
|
||||||
On Arreas Aging
|
<mat-label>On arrears ageing</mat-label>
|
||||||
</mat-checkbox>
|
<input type="number" matInput formControlName="graceOnArrearsAgeing">
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field fxFlex="48%" *ngIf="loansAccountTemplate?.canDefineInstallmentAmount">
|
<mat-form-field fxFlex="48%" *ngIf="loansAccountTemplate?.canDefineInstallmentAmount">
|
||||||
<mat-label>Installment Amount</mat-label>
|
<mat-label>Installment Amount</mat-label>
|
||||||
@@ -360,7 +360,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div fxFlexFill
|
<div fxFlexFill
|
||||||
@@ -419,8 +418,8 @@
|
|||||||
<tr mat-header-row *matHeaderRowDef="loanCollateralDisplayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="loanCollateralDisplayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: loanCollateralDisplayedColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: loanCollateralDisplayedColumns;"></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
<button mat-raised-button matStepperPrevious>
|
<button mat-raised-button matStepperPrevious>
|
||||||
<fa-icon icon="arrow-left"></fa-icon>
|
<fa-icon icon="arrow-left"></fa-icon>
|
||||||
|
|||||||
-1
@@ -10,7 +10,6 @@ import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.componen
|
|||||||
import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base';
|
import { DatepickerBase } from 'app/shared/form-dialog/formfield/model/datepicker-base';
|
||||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||||
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||||
import { any } from 'cypress/types/bluebird';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Loans Account Terms Step
|
* Create Loans Account Terms Step
|
||||||
|
|||||||
+6
-6
@@ -34,18 +34,18 @@
|
|||||||
<td mat-footer-cell *matFooterCellDef> </td>
|
<td mat-footer-cell *matFooterCellDef> </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="principalDue">
|
|
||||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Principal Due </th>
|
|
||||||
<td mat-cell class="check r-amount" *matCellDef="let ele"> {{ ele.principalDue | number }} </td>
|
|
||||||
<td mat-footer-cell class="check r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalPrincipalExpected | currency }}</b> </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="balanceOfLoan">
|
<ng-container matColumnDef="balanceOfLoan">
|
||||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Balance Of Loan </th>
|
<th mat-header-cell class="r-amount" *matHeaderCellDef> Balance Of Loan </th>
|
||||||
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.principalLoanBalanceOutstanding | number }} </td>
|
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.principalLoanBalanceOutstanding | number }} </td>
|
||||||
<td mat-footer-cell class="r-amount" *matFooterCellDef> </td>
|
<td mat-footer-cell class="r-amount" *matFooterCellDef> </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="principalDue">
|
||||||
|
<th mat-header-cell class="r-amount" *matHeaderCellDef> Principal Due </th>
|
||||||
|
<td mat-cell class="check r-amount" *matCellDef="let ele"> {{ ele.principalDue | number }} </td>
|
||||||
|
<td mat-footer-cell class="check r-amount" *matFooterCellDef> <b> {{ repaymentScheduleDetails.totalPrincipalExpected | currency }}</b> </td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="interest">
|
<ng-container matColumnDef="interest">
|
||||||
<th mat-header-cell class="r-amount" *matHeaderCellDef> Interest </th>
|
<th mat-header-cell class="r-amount" *matHeaderCellDef> Interest </th>
|
||||||
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.interestOriginalDue | number}} </td>
|
<td mat-cell class="r-amount" *matCellDef="let ele"> {{ ele.interestOriginalDue | number}} </td>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -8,13 +8,14 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
})
|
})
|
||||||
export class RepaymentScheduleTabComponent implements OnInit {
|
export class RepaymentScheduleTabComponent implements OnInit {
|
||||||
|
|
||||||
loanDetails: any;
|
|
||||||
/** Loan Repayment Schedule Details Data */
|
/** Loan Repayment Schedule Details Data */
|
||||||
repaymentScheduleDetails: any;
|
@Input() repaymentScheduleDetails: any = null;
|
||||||
|
loanDetailsDataRepaymentSchedule: any = [];
|
||||||
|
|
||||||
/** Stores if there is any waived amount */
|
/** Stores if there is any waived amount */
|
||||||
isWaived: boolean;
|
isWaived: boolean;
|
||||||
/** Columns to be displayed in original schedule table. */
|
/** Columns to be displayed in original schedule table. */
|
||||||
displayedColumns: string[] = ['number', 'days', 'date', 'paiddate', 'check', 'principalDue', 'balanceOfLoan', 'interest', 'fees', 'penalties', 'due', 'paid', 'inadvance', 'late', 'waived', 'outstanding'];
|
displayedColumns: string[] = ['number', 'days', 'date', 'paiddate', 'check', 'balanceOfLoan', 'principalDue', 'interest', 'fees', 'penalties', 'due', 'paid', 'inadvance', 'late', 'waived', 'outstanding'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the loans with associations data from `resolve`.
|
* Retrieves the loans with associations data from `resolve`.
|
||||||
@@ -22,12 +23,14 @@ export class RepaymentScheduleTabComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
constructor(private route: ActivatedRoute) {
|
constructor(private route: ActivatedRoute) {
|
||||||
this.route.parent.data.subscribe((data: { loanDetailsData: any }) => {
|
this.route.parent.data.subscribe((data: { loanDetailsData: any }) => {
|
||||||
this.loanDetails = data.loanDetailsData;
|
this.loanDetailsDataRepaymentSchedule = data.loanDetailsData.repaymentSchedule;
|
||||||
this.repaymentScheduleDetails = data.loanDetailsData.repaymentSchedule;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
if (this.repaymentScheduleDetails == null) {
|
||||||
|
this.repaymentScheduleDetails = this.loanDetailsDataRepaymentSchedule;
|
||||||
|
}
|
||||||
this.isWaived = this.repaymentScheduleDetails.totalWaived > 0;
|
this.isWaived = this.repaymentScheduleDetails.totalWaived > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ import { LoansAccountAddCollateralDialogComponent } from './custom-dialog/loans-
|
|||||||
import { LoanAccountLoadDocumentsDialogComponent } from './custom-dialog/loan-account-load-documents-dialog/loan-account-load-documents-dialog.component';
|
import { LoanAccountLoadDocumentsDialogComponent } from './custom-dialog/loan-account-load-documents-dialog/loan-account-load-documents-dialog.component';
|
||||||
import { LoanCreditBalanceRefundComponent } from './loans-view/loan-account-actions/loan-credit-balance-refund/loan-credit-balance-refund.component';
|
import { LoanCreditBalanceRefundComponent } from './loans-view/loan-account-actions/loan-credit-balance-refund/loan-credit-balance-refund.component';
|
||||||
import { LoanDelinquencyTagsTabComponent } from './loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component';
|
import { LoanDelinquencyTagsTabComponent } from './loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component';
|
||||||
|
import { LoansAccountScheduleStepComponent } from './loans-account-stepper/loans-account-schedule-step/loans-account-schedule-step.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loans Module
|
* Loans Module
|
||||||
@@ -142,7 +143,8 @@ import { LoanDelinquencyTagsTabComponent } from './loans-view/loan-delinquency-t
|
|||||||
GlimChargesStepComponent,
|
GlimChargesStepComponent,
|
||||||
GlimTermsStepComponent,
|
GlimTermsStepComponent,
|
||||||
GlimPreviewStepComponent,
|
GlimPreviewStepComponent,
|
||||||
LoanDelinquencyTagsTabComponent
|
LoanDelinquencyTagsTabComponent,
|
||||||
|
LoansAccountScheduleStepComponent
|
||||||
],
|
],
|
||||||
providers: [ ],
|
providers: [ ],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { HttpClient, HttpParams } from '@angular/common/http';
|
|||||||
|
|
||||||
/** rxjs Imports */
|
/** rxjs Imports */
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
import { Dates } from 'app/core/utils/dates';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loans service.
|
* Loans service.
|
||||||
@@ -12,7 +13,8 @@ import { Observable } from 'rxjs';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class LoansService {
|
export class LoansService {
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient,
|
||||||
|
private dateUtils: Dates) { }
|
||||||
/**
|
/**
|
||||||
* @param {string} loanId loanId of the loan.
|
* @param {string} loanId loanId of the loan.
|
||||||
* @returns {Observable<any>}
|
* @returns {Observable<any>}
|
||||||
@@ -470,4 +472,73 @@ export class LoansService {
|
|||||||
return this.http.post('/batches?enclosingTransaction=true', glimAccount);
|
return this.http.post('/batches?enclosingTransaction=true', glimAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculateLoanSchedule(payload: any): Observable<any> {
|
||||||
|
return this.http.post('/loans?command=calculateLoanSchedule', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loansAccount Loan account data used for the request
|
||||||
|
* @param loansAccountTemplate Loan account template for getting product default values
|
||||||
|
* @param calendarOptions Calendar options
|
||||||
|
* @param locale String to send to backend
|
||||||
|
* @param dateFormat String with date format to manage dates
|
||||||
|
* @returns Object with Loan Account payload data.
|
||||||
|
*/
|
||||||
|
buildLoanRequestPayload(loansAccount: any, loansAccountTemplate: any, calendarOptions: any, locale: string, dateFormat: string): any {
|
||||||
|
const loansAccountData = {
|
||||||
|
...loansAccount,
|
||||||
|
charges: loansAccount.charges.map((charge: any) => ({
|
||||||
|
chargeId: charge.id,
|
||||||
|
amount: charge.amount,
|
||||||
|
dueDate: charge.dueDate && this.dateUtils.formatDate(charge.dueDate, dateFormat),
|
||||||
|
})),
|
||||||
|
collateral: loansAccount.collateral.map((collateralEle: any) => ({
|
||||||
|
clientCollateralId: collateralEle.type.collateralId,
|
||||||
|
quantity: collateralEle.value,
|
||||||
|
})),
|
||||||
|
disbursementData: loansAccount.disbursementData.map((item: any) => ({
|
||||||
|
expectedDisbursementDate: this.dateUtils.formatDate(item.expectedDisbursementDate, dateFormat),
|
||||||
|
principal: item.principal
|
||||||
|
})),
|
||||||
|
interestChargedFromDate: this.dateUtils.formatDate(loansAccount.interestChargedFromDate, dateFormat),
|
||||||
|
repaymentsStartingFromDate: this.dateUtils.formatDate(loansAccount.repaymentsStartingFromDate, dateFormat),
|
||||||
|
submittedOnDate: this.dateUtils.formatDate(loansAccount.submittedOnDate, dateFormat),
|
||||||
|
expectedDisbursementDate: this.dateUtils.formatDate(loansAccount.expectedDisbursementDate, dateFormat),
|
||||||
|
dateFormat,
|
||||||
|
locale,
|
||||||
|
};
|
||||||
|
if (loansAccountTemplate.clientId) {
|
||||||
|
loansAccountData.clientId = loansAccountTemplate.clientId;
|
||||||
|
loansAccountData.loanType = 'individual';
|
||||||
|
} else {
|
||||||
|
loansAccountData.groupId = loansAccountTemplate.group.id;
|
||||||
|
loansAccountData.loanType = 'group';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loansAccountData.syncRepaymentsWithMeeting) {
|
||||||
|
loansAccountData.calendarId = calendarOptions[0].id;
|
||||||
|
delete loansAccountData.syncRepaymentsWithMeeting;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loansAccountData.recalculationRestFrequencyDate) {
|
||||||
|
loansAccountData.recalculationRestFrequencyDate = this.dateUtils.formatDate(loansAccount.recalculationRestFrequencyDate, dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loansAccountData.interestCalculationPeriodType === 0) {
|
||||||
|
loansAccountData.allowPartialPeriodInterestCalcualtion = false;
|
||||||
|
}
|
||||||
|
if (!(loansAccountData.isFloatingInterestRate === false)) {
|
||||||
|
delete loansAccountData.isFloatingInterestRate;
|
||||||
|
}
|
||||||
|
if (!(loansAccountData.multiDisburseLoan)) {
|
||||||
|
delete loansAccountData.disbursementData;
|
||||||
|
}
|
||||||
|
delete loansAccountData.isValid;
|
||||||
|
loansAccountData.principal = loansAccountData.principalAmount;
|
||||||
|
delete loansAccountData.principalAmount;
|
||||||
|
|
||||||
|
return loansAccountData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user