feat: collateral module
This commit is contained in:
@@ -47,7 +47,7 @@
|
||||
|
||||
<mifosx-loans-account-charges-step [loansAccountProductTemplate]="loansAccountProductTemplate"
|
||||
[loansAccountTemplate]="loansAccountTemplate" [collateralOptions]="collateralOptions"
|
||||
[loansAccountFormValid]="loansAccountFormValid">
|
||||
[loansAccountFormValid]="loansAccountFormValid" [loanPrincipal]="loanPrincipal">
|
||||
</mifosx-loans-account-charges-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
/** Custom Services */
|
||||
import { LoansService } from '../loans.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { ClientsService } from 'app/clients/clients.service';
|
||||
|
||||
/** Step Components */
|
||||
import { LoansAccountDetailsStepComponent } from '../loans-account-stepper/loans-account-details-step/loans-account-details-step.component';
|
||||
@@ -35,6 +36,8 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
collateralOptions: any;
|
||||
/** Multi Disburse Loan */
|
||||
multiDisburseLoan: any;
|
||||
/** Principal Amount */
|
||||
principal: any;
|
||||
|
||||
/**
|
||||
* Sets loans account create form.
|
||||
@@ -43,12 +46,14 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
* @param {Dates} dateUtils Date Utils
|
||||
* @param {loansService} LoansService Loans Service
|
||||
* @param {SettingsService} settingsService Settings Service
|
||||
* @param {ClientsService} clientService Client Service
|
||||
*/
|
||||
constructor(private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private dateUtils: Dates,
|
||||
private loansService: LoansService,
|
||||
private settingsService: SettingsService
|
||||
private settingsService: SettingsService,
|
||||
private clientService: ClientsService
|
||||
) {
|
||||
this.route.data.subscribe((data: { loansAccountTemplate: any }) => {
|
||||
this.loansAccountTemplate = data.loansAccountTemplate;
|
||||
@@ -64,8 +69,9 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
*/
|
||||
setTemplate($event: any) {
|
||||
this.loansAccountProductTemplate = $event;
|
||||
this.loansService.getLoansCollateralTemplateResource(this.loansAccountProductTemplate.loanProductId).subscribe((response: any) => {
|
||||
this.collateralOptions = response.loanCollateralOptions;
|
||||
const clientId = this.loansAccountTemplate.clientId;
|
||||
this.clientService.getCollateralTemplate(clientId).subscribe((response: any) => {
|
||||
this.collateralOptions = response;
|
||||
});
|
||||
const entityId = (this.loansAccountTemplate.clientId) ? this.loansAccountTemplate.clientId : this.loansAccountTemplate.group.id;
|
||||
const isGroup = (this.loansAccountTemplate.clientId) ? false : true;
|
||||
@@ -89,10 +95,16 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
get loansAccountFormValid() {
|
||||
return (
|
||||
this.loansAccountDetailsForm.valid &&
|
||||
this.loansAccountTermsForm.valid
|
||||
this.loansAccountTermsForm.valid &&
|
||||
this.loansAccountChargesStep.loansAccountCharges.isValid
|
||||
);
|
||||
}
|
||||
|
||||
/** Gets principal Amount */
|
||||
get loanPrincipal() {
|
||||
return this.loansAccountTermsStep.loansAccountTermsForm.value.principal;
|
||||
}
|
||||
|
||||
/** Retrieves Data of all forms except Currency to submit the data */
|
||||
get loansAccount() {
|
||||
return {
|
||||
@@ -116,9 +128,8 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
dueDate: charge.dueDate && this.dateUtils.formatDate(charge.dueDate, dateFormat),
|
||||
})),
|
||||
collateral: this.loansAccount.collateral.map((collateralEle: any) => ({
|
||||
type: collateralEle.type,
|
||||
value: collateralEle.value,
|
||||
description: collateralEle.description
|
||||
clientCollateralId: collateralEle.type.collateralId,
|
||||
quantity: collateralEle.value,
|
||||
})),
|
||||
disbursementData: this.loansAccount.disbursementData.map((item: any) => ({
|
||||
expectedDisbursementDate: this.dateUtils.formatDate(item.expectedDisbursementDate, dateFormat),
|
||||
@@ -157,6 +168,7 @@ export class CreateLoansAccountComponent implements OnInit {
|
||||
if (!(this.multiDisburseLoan)) {
|
||||
delete loansAccountData.disbursementData;
|
||||
}
|
||||
delete loansAccountData.isValid;
|
||||
|
||||
this.loansService.createLoansAccount(loansAccountData).subscribe((response: any) => {
|
||||
this.router.navigate(['../', response.resourceId], { relativeTo: this.route });
|
||||
|
||||
+18
-13
@@ -3,31 +3,36 @@
|
||||
<div mat-dialog-content [formGroup]="addCollateralForm" fxLayout="column">
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Collateral Type</mat-label>
|
||||
<mat-select formControlName="type" required>
|
||||
<mat-option *ngFor="let collateralType of collateralTypeData" [value]="collateralType.id">
|
||||
<mat-label>Collateral</mat-label>
|
||||
<mat-select formControlName="collateral" required>
|
||||
<mat-option *ngFor="let collateralType of collateralTypeData" [value]="collateralType" >
|
||||
{{ collateralType.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Collateral Type is <strong>required</strong>
|
||||
Collateral is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Value</mat-label>
|
||||
<input type="number" matInput formControlName="value" required>
|
||||
<mat-error>
|
||||
Value is <strong>required</strong>
|
||||
<mat-label>Quantity</mat-label>
|
||||
<input type="number" [max]="maxQuantity" [min]="0" matInput formControlName="quantity" required>
|
||||
<mat-error *ngIf="addCollateralForm.controls.quantity.hasError('required')">
|
||||
Quantity is <strong>required</strong>
|
||||
</mat-error>
|
||||
<mat-error *ngIf="addCollateralForm.controls.quantity.hasError('max')">
|
||||
Quantity can not be more than <strong>{{ maxQuantity }}</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Description</mat-label>
|
||||
<input type="text" matInput formControlName="description" required>
|
||||
<mat-error>
|
||||
Description is <strong>required</strong>
|
||||
</mat-error>
|
||||
<mat-label>Total Value</mat-label>
|
||||
<input type="text" matInput formControlName="totalValue" [disabled]="true">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Total Collateral Value</mat-label>
|
||||
<input type="text" matInput formControlName="totalCollateralValue" [disabled]="true">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
+28
-4
@@ -16,7 +16,12 @@ export class LoansAccountAddCollateralDialogComponent implements OnInit {
|
||||
};
|
||||
|
||||
addCollateralForm: FormGroup;
|
||||
/** All Collateral Options */
|
||||
collateralTypeData: any;
|
||||
/** Selected Collateral */
|
||||
collateralData: any;
|
||||
/** Maximum ALlowed Quantity of selected collateral */
|
||||
maxQuantity: any = 0;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<LoansAccountAddCollateralDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
@@ -26,14 +31,33 @@ export class LoansAccountAddCollateralDialogComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
this.dialogRef.updateSize('400px');
|
||||
this.collateralTypeData = this.data.collateralTypeOptions;
|
||||
this.collateralTypeData = this.data.collateralOptions;
|
||||
this.buildDependencies();
|
||||
}
|
||||
|
||||
createAddCollateralForm() {
|
||||
this.addCollateralForm = this.formBuilder.group({
|
||||
'type': ['', Validators.required],
|
||||
'value': ['', Validators.required],
|
||||
'description': ['', Validators.required]
|
||||
'collateral': ['', Validators.required],
|
||||
'quantity': ['', Validators.required],
|
||||
'totalValue': [{value: '', disabled: true}],
|
||||
'totalCollateralValue': [{value: '', disabled: true}],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to Form controls value changes
|
||||
*/
|
||||
buildDependencies() {
|
||||
this.addCollateralForm.controls.collateral.valueChanges.subscribe((collateral: any) => {
|
||||
this.collateralData = collateral;
|
||||
this.maxQuantity = collateral.quantity;
|
||||
});
|
||||
|
||||
this.addCollateralForm.controls.quantity.valueChanges.subscribe((quantity: any) => {
|
||||
this.addCollateralForm.patchValue({
|
||||
'totalValue': this.collateralData.basePrice * quantity,
|
||||
'totalCollateralValue': this.collateralData.basePrice * this.collateralData.pctToBase * quantity / 100
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+11
-6
@@ -135,18 +135,23 @@
|
||||
<table mat-table class="mat-elevation-z1" [dataSource]="collateralDataSource">
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.type.name }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef> Value </th>
|
||||
<th mat-header-cell *matHeaderCellDef> Quantity </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.value }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef> Description </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.description }} </td>
|
||||
<ng-container matColumnDef="totalValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Total Value </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.type.basePrice*ele.value }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="totalCollateralValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Total Collateral Value </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.type.pctToBase*ele.type.basePrice*ele.value/100 }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="action">
|
||||
@@ -169,7 +174,7 @@
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext [disabled]="!loansAccountFormValid">
|
||||
<button mat-raised-button matStepperNext [disabled]="!isCollateralSufficient">
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
|
||||
+38
-11
@@ -31,8 +31,10 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
@Input() loansAccountTemplate: any;
|
||||
// @Input() loansAccountFormValid: LoansAccountFormValid
|
||||
@Input() loansAccountFormValid: boolean;
|
||||
// @Input collateralOptionsL Collateral Options
|
||||
// @Input collateralOptions: Collateral Options
|
||||
@Input() collateralOptions: any;
|
||||
// @Input loanPrincipal: Loan Principle
|
||||
@Input() loanPrincipal: any;
|
||||
|
||||
/** Charges Data */
|
||||
chargeData: any;
|
||||
@@ -47,9 +49,13 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
/** Columns to be displayed in overdue charges table. */
|
||||
overdueChargesDisplayedColumns: string[] = ['name', 'type', 'amount', 'collectedon'];
|
||||
/** Columns to be displayed in collateral table. */
|
||||
loanCollateralDisplayedColumns: string[] = ['type', 'value', 'description', 'action'];
|
||||
loanCollateralDisplayedColumns: string[] = ['type', 'value', 'totalValue', 'totalCollateralValue', 'action'];
|
||||
/** Component is pristine if there has been no changes by user interaction */
|
||||
pristine = true;
|
||||
/** Check if value of collateral added is more than principal amount */
|
||||
isCollateralSufficient = false;
|
||||
/** Total value of all collateral added to a loan */
|
||||
totalCollateralValue: any = 0;
|
||||
|
||||
/**
|
||||
* Loans Account Charges Form Step
|
||||
@@ -207,33 +213,53 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Needs to be completed
|
||||
/**
|
||||
* Add a Collateral to the loan
|
||||
*/
|
||||
addCollateral() {
|
||||
const addCollateralDialogRef = this.dialog.open(LoansAccountAddCollateralDialogComponent, {
|
||||
data: { collateralOptions: this.collateralOptions }
|
||||
});
|
||||
console.log(this.collateralOptions);
|
||||
addCollateralDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.addCollateralForm) {
|
||||
console.log(this.loanPrincipal);
|
||||
if (response.data) {
|
||||
const collateralData = {
|
||||
type: response.addCollateralForm.value.type,
|
||||
value: response.addCollateralForm.value.value,
|
||||
description: response.addCollateralForm.value.description
|
||||
type: response.data.value.collateral,
|
||||
value: response.data.value.quantity,
|
||||
};
|
||||
this.collateralDataSource = this.collateralDataSource.concat(collateralData);
|
||||
|
||||
this.totalCollateralValue += collateralData.type.pctToBase * collateralData.type.basePrice * collateralData.value / 100;
|
||||
this.collateralDataSource = this.collateralDataSource.concat(collateralData);
|
||||
this.collateralOptions = this.collateralOptions.filter( (user: any) => user.collateralId !== response.data.value.collateral.collateralId);
|
||||
if (this.loanPrincipal < this.totalCollateralValue) {
|
||||
this.isCollateralSufficient = true;
|
||||
} else {
|
||||
this.isCollateralSufficient = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a added collateral from loan
|
||||
* @param id ID od the collateral to be deleted
|
||||
*/
|
||||
deleteCollateral(id: any) {
|
||||
const deleteCollateralDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `collateral` }
|
||||
});
|
||||
deleteCollateralDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
this.collateralDataSource.splice(this.collateralDataSource.indexOf(id), 1);
|
||||
const removed: any = this.collateralDataSource.splice(id, 1);
|
||||
this.collateralOptions = this.collateralOptions.concat(removed[0].type);
|
||||
this.totalCollateralValue -= removed[0].type.pctToBase * removed[0].type.basePrice * removed[0].value / 100;
|
||||
this.collateralDataSource = this.collateralDataSource.concat([]);
|
||||
this.pristine = false;
|
||||
if (this.loanPrincipal < this.totalCollateralValue) {
|
||||
this.isCollateralSufficient = true;
|
||||
} else {
|
||||
this.isCollateralSufficient = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -244,7 +270,8 @@ export class LoansAccountChargesStepComponent implements OnInit, OnChanges {
|
||||
get loansAccountCharges() {
|
||||
return {
|
||||
charges: this.chargesDataSource,
|
||||
collateral: this.collateralDataSource
|
||||
collateral: this.collateralDataSource,
|
||||
isValid: this.isCollateralSufficient
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,19 +2,24 @@
|
||||
|
||||
<table mat-table [dataSource]="loanDetails.collateral">
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.type.name }} </td>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef> ID </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.clientCollateralId }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<th mat-header-cell *matHeaderCellDef> Value </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.value }} </td>
|
||||
<ng-container matColumnDef="quantity">
|
||||
<th mat-header-cell *matHeaderCellDef> Quantity </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.quantity }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef> Description </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.description }} </td>
|
||||
<ng-container matColumnDef="total">
|
||||
<th mat-header-cell *matHeaderCellDef> Total Value </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.total }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="totalCollateral">
|
||||
<th mat-header-cell *matHeaderCellDef> Total Collateral Value </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.totalCollateral }} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
|
||||
@@ -11,7 +11,7 @@ export class LoanCollateralTabComponent implements OnInit {
|
||||
/** Loan Details */
|
||||
loanDetails: any;
|
||||
/** Columns to be displayed in collateral table. */
|
||||
displayedColumns: string[] = ['type', 'value', 'description'];
|
||||
displayedColumns: string[] = ['id', 'quantity', 'total', 'totalCollateral'];
|
||||
|
||||
/**
|
||||
* Retrieves the loans data from `resolve`.
|
||||
|
||||
Reference in New Issue
Block a user