feat: add loans view page (#661)
- Add loan account page - Add general tab - Add account details tab Fixes: #219
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
<div class="tab-container mat-typography">
|
||||
|
||||
<ng-container *ngIf="loanDetails.summary">
|
||||
<h3>Performance History</h3>
|
||||
<div fxLayout="row" fxLayoutGap="32px" class="performance-history-container">
|
||||
<p>
|
||||
# of Repayments :{{loanDetails?.numberOfRepayments}}
|
||||
<p>
|
||||
Maturity Date :{{loanDetails?.timeline.expectedMaturityDate | date}}
|
||||
</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="loanDetails.summary">
|
||||
|
||||
<h3> Loan Summary </h3>
|
||||
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="Empty">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.property }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Original">
|
||||
<th mat-header-cell *matHeaderCellDef> Original </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.original | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Paid">
|
||||
<th mat-header-cell *matHeaderCellDef> Paid </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.paid | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Waived">
|
||||
<th mat-header-cell *matHeaderCellDef> Waived </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.waived | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Written Off">
|
||||
<th mat-header-cell *matHeaderCellDef> Written Off </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.writtenOff | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Outstanding">
|
||||
<th mat-header-cell *matHeaderCellDef> Outstanding </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.outstanding | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Over Due">
|
||||
<th mat-header-cell *matHeaderCellDef> Over Due </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.overdue | number }} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="loanSummaryColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: loanSummaryColumns;"></tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanDetails.summary">
|
||||
|
||||
<h3> Loan Details</h3>
|
||||
<table mat-table [dataSource]="detailsDataSource">
|
||||
|
||||
<ng-container matColumnDef="Key">
|
||||
<th mat-header-cell *matHeaderCellDef> Key </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.key }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Value">
|
||||
<th mat-header-cell *matHeaderCellDef> Value </th>
|
||||
<td mat-cell *matCellDef="let ele">
|
||||
<ng-container *ngIf="ele.key === 'Disbursement Date'" >
|
||||
<span *ngIf="loanDetails.timeline.actualDisbursementDate"> {{loanDetails.timeline.actualDisbursementDate | date}} </span>
|
||||
<span *ngIf="!loanDetails.timeline.actualDisbursementDate"> Not Available </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Loan Purpose'">
|
||||
<span *ngIf="loanDetails.loanPurchaseName"> {{loanDetails.loanPurchaseName}} </span>
|
||||
<span *ngIf="!loanDetails.loanPurchaseName"> Not Available </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Loan Officer'">
|
||||
<span *ngIf="!loanDetails.loanOfficerName"> Unassigned </span>
|
||||
<span *ngIf="loanDetails.loanOfficerName"> {{loanDetails.loanOfficerName}}
|
||||
<span *ngIf="loanDetails.loanOfficerName">
|
||||
<!-- <a ng-click="clickEvent('unassignloanofficer', loanDetails.id)" *mifosxHasPermission = "'REMOVELOANOFFICER_LOAN'"><i
|
||||
class="fa fa-times"></i></a> -->
|
||||
</span>
|
||||
</span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Currency'">
|
||||
<span> {{loanDetails.currency.name }} {{loanDetails.currency.code}} </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'External Id'">
|
||||
<span *ngIf="loanDetails.externalId"> {{loanDetails.externalId}} </span>
|
||||
<span *ngIf="!loanDetails.externalId"> Not Available </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Proposed Amount' || ele.key === 'Approved Amount' || ele.key === 'Disburse Amount'">
|
||||
{{ ele.value }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="loanDetailsColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: loanDetailsColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loanDetails.summary">
|
||||
|
||||
<h3> Loan Details </h3>
|
||||
<table mat-table [dataSource]="detailsDataSource">
|
||||
|
||||
<ng-container matColumnDef="Key">
|
||||
<th mat-header-cell *matHeaderCellDef> Key </th>
|
||||
<td mat-cell *matCellDef="let ele"> {{ ele.key }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="Value">
|
||||
<th mat-header-cell *matHeaderCellDef> Value </th>
|
||||
<td mat-cell *matCellDef="let ele">
|
||||
<ng-container *ngIf="ele.key === 'Disbursement Date'" >
|
||||
<span *ngIf="loanDetails.timeline.actualDisbursementDate"> {{loanDetails.timeline.actualDisbursementDate | date}} </span>
|
||||
<span *ngIf="!loanDetails.timeline.actualDisbursementDate"> Not Available </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Loan Officer'">
|
||||
<span *ngIf="!loanDetails.loanOfficerName"> Unassigned </span>
|
||||
<span *ngIf="loanDetails.loanOfficerName"> {{loanDetails.loanOfficerName}}
|
||||
<span *ngIf="loanDetails.loanOfficerName">
|
||||
<!-- <a ng-click="clickEvent('unassignloanofficer', loanDetails.id)" *mifosxHasPermission = "'REMOVELOANOFFICER_LOAN'"><i
|
||||
class="fa fa-times"></i></a> -->
|
||||
</span>
|
||||
</span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'Currency'">
|
||||
<span> {{loanDetails.currency.name }} </span>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="ele.key === 'External Id'">
|
||||
<span *ngIf="loanDetails.externalId"> {{loanDetails.externalId}} </span>
|
||||
<span *ngIf="!loanDetails.externalId"> Not Available </span>
|
||||
</ng-container>
|
||||
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="loanDetailsColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: loanDetailsColumns;"></tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loanDetails.summary">
|
||||
<h3> Loan Purpose </h3>
|
||||
<div class="container">
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%">Loan Purpose:</span>
|
||||
<span fxFlex="50%" *ngIf="loanDetails.loanPurposeName">
|
||||
{{ loanDetails.loanPurposeName }}
|
||||
</span>
|
||||
<span fxFlex="50%" *ngIf="!loanDetails.loanPurposeName">
|
||||
Not Provided
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%">Proposed Amount:</span>
|
||||
<span fxFlex="50%">{{ loanDetails.proposedPrincipal | number}}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="showApprovedAmountBasedOnStatus()">
|
||||
<span fxFlex="50%">Approved Amount:</span>
|
||||
<span fxFlex="50%">{{ loanDetails.approvedPrincipal | number }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="showDisbursedAmountBasedOnStatus()">
|
||||
<span fxFlex="50%">Disburse Amount:</span>
|
||||
<span fxFlex="50%">{{ loanDetails.principal | number }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%">Arrears By:</span>
|
||||
<span fxFlex="50%"> Not Provided</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
|
||||
h3{
|
||||
margin:1% auto;
|
||||
}
|
||||
.performance-history-container {
|
||||
border: 1px solid;
|
||||
padding: 1%;
|
||||
margin-bottom: 20px ;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GeneralTabComponent } from './general-tab.component';
|
||||
|
||||
describe('GeneralTabComponent', () => {
|
||||
let component: GeneralTabComponent;
|
||||
let fixture: ComponentFixture<GeneralTabComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ GeneralTabComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GeneralTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,169 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { MatTableDataSource } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-general-tab',
|
||||
templateUrl: './general-tab.component.html',
|
||||
styleUrls: ['./general-tab.component.scss']
|
||||
})
|
||||
export class GeneralTabComponent implements OnInit {
|
||||
|
||||
loanDetails: any;
|
||||
status: any;
|
||||
loanSummaryColumns: string[] = ['Empty', 'Original', 'Paid', 'Waived', 'Written Off', 'Outstanding', 'Over Due'];
|
||||
loanDetailsColumns: string[] = ['Key', 'Value'];
|
||||
loanSummaryTableData: {
|
||||
'property': string,
|
||||
'original': string,
|
||||
'paid': string,
|
||||
'waived': string,
|
||||
'writtenOff': string,
|
||||
'outstanding': string,
|
||||
'overdue': string
|
||||
}[];
|
||||
loanDetailsTableData: {
|
||||
'key': string,
|
||||
'value'?: string
|
||||
}[];
|
||||
|
||||
/** Data source for loans summary table. */
|
||||
dataSource: MatTableDataSource<any>;
|
||||
detailsDataSource: MatTableDataSource<any>;
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { loanDetailsData: any, }) => {
|
||||
this.loanDetails = data.loanDetailsData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.status = this.loanDetails.value;
|
||||
if (this.loanDetails.summary) {
|
||||
this.setloanSummaryTableData();
|
||||
this.setloanDetailsTableData();
|
||||
} else {
|
||||
this.setloanNonDetailsTableData();
|
||||
}
|
||||
}
|
||||
|
||||
setloanSummaryTableData() {
|
||||
this.loanSummaryTableData = [
|
||||
{
|
||||
'property': 'Principal',
|
||||
'original': this.loanDetails.summary.principalDisbursed,
|
||||
'paid': this.loanDetails.summary.principalPaid,
|
||||
'waived': this.loanDetails.summary.principalWrittenOff,
|
||||
'writtenOff': this.loanDetails.summary.principalOutstanding,
|
||||
'outstanding': this.loanDetails.summary.principalOutstanding,
|
||||
'overdue': this.loanDetails.summary.principalOverdue,
|
||||
|
||||
},
|
||||
{
|
||||
'property': 'Interest',
|
||||
'original': this.loanDetails.summary.interestCharged,
|
||||
'paid': this.loanDetails.summary.interestPaid,
|
||||
'waived': this.loanDetails.summary.interestWaived,
|
||||
'writtenOff': this.loanDetails.summary.interestWrittenOff,
|
||||
'outstanding': this.loanDetails.summary.interestOutstanding,
|
||||
'overdue': this.loanDetails.summary.interestOverdue,
|
||||
},
|
||||
{
|
||||
'property': 'Fees',
|
||||
'original': this.loanDetails.summary.feeChargesCharged,
|
||||
'paid': this.loanDetails.summary.feeChargesPaid,
|
||||
'waived': this.loanDetails.summary.feeChargesWaived,
|
||||
'writtenOff': this.loanDetails.summary.feeChargesWrittenOff,
|
||||
'outstanding': this.loanDetails.summary.feeChargesOutstanding,
|
||||
'overdue': this.loanDetails.summary.feeChargesOverdue,
|
||||
},
|
||||
{
|
||||
'property': 'Penalties',
|
||||
'original': this.loanDetails.summary.penaltyChargesCharged,
|
||||
'paid': this.loanDetails.summary.penaltyChargesPaid,
|
||||
'waived': this.loanDetails.summary.penaltyChargesWaived,
|
||||
'writtenOff': this.loanDetails.summary.penaltyChargesWrittenOff,
|
||||
'outstanding': this.loanDetails.summary.penaltyChargesOutstanding,
|
||||
'overdue': this.loanDetails.summary.penaltyChargesOverdue,
|
||||
},
|
||||
{
|
||||
'property': 'Total',
|
||||
'original': this.loanDetails.summary.totalExpectedRepayment,
|
||||
'paid': this.loanDetails.summary.totalRepayment,
|
||||
'waived': this.loanDetails.summary.totalWaived,
|
||||
'writtenOff': this.loanDetails.summary.totalWrittenOff,
|
||||
'outstanding': this.loanDetails.summary.totalOutstanding,
|
||||
'overdue': this.loanDetails.summary.totalOverdue,
|
||||
}
|
||||
];
|
||||
this.dataSource = new MatTableDataSource(this.loanSummaryTableData);
|
||||
}
|
||||
|
||||
setloanDetailsTableData() {
|
||||
|
||||
this.loanDetailsTableData = [
|
||||
{
|
||||
'key': 'Disbursement Date'
|
||||
},
|
||||
{
|
||||
'key': 'Loan Purpose'
|
||||
},
|
||||
{
|
||||
'key': 'Loan Officer'
|
||||
},
|
||||
{
|
||||
'key': 'Currency'
|
||||
},
|
||||
{
|
||||
'key': 'External Id'
|
||||
},
|
||||
{
|
||||
'key': 'Proposed Amount',
|
||||
'value': this.loanDetails.proposedPrincipal,
|
||||
},
|
||||
{
|
||||
'key': 'Approved Amount',
|
||||
'value': this.loanDetails.approvedPrincipal,
|
||||
},
|
||||
{
|
||||
'key': 'Disburse Amount',
|
||||
'value': this.loanDetails.principal,
|
||||
},
|
||||
];
|
||||
this.detailsDataSource = new MatTableDataSource(this.loanDetailsTableData);
|
||||
|
||||
}
|
||||
|
||||
setloanNonDetailsTableData() {
|
||||
this.loanDetailsTableData = [
|
||||
{
|
||||
'key': 'Disbursement Date'
|
||||
},
|
||||
{
|
||||
'key': 'Currency'
|
||||
},
|
||||
{
|
||||
'key': 'Loan Officer'
|
||||
},
|
||||
{
|
||||
'key': 'External Id'
|
||||
}
|
||||
];
|
||||
this.detailsDataSource = new MatTableDataSource(this.loanDetailsTableData);
|
||||
}
|
||||
|
||||
showApprovedAmountBasedOnStatus() {
|
||||
if (this.status === 'Submitted and pending approval' || this.status === 'Withdrawn by applicant' || this.status === 'Rejected') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
showDisbursedAmountBasedOnStatus = function() {
|
||||
if (this.status === 'Submitted and pending approval' || this.status === 'Withdrawn by applicant' || this.status === 'Rejected' ||
|
||||
this.status === 'Approved') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user