feat: add loans view page (#661)
- Add loan account page - Add general tab - Add account details tab Fixes: #219
This commit is contained in:
@@ -160,6 +160,11 @@ const routes: Routes = [
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'loans',
|
||||
data: { title: extract('Loans'), breadcrumb: 'loans' },
|
||||
loadChildren: '../loans/loans.module#LoansModule'
|
||||
}
|
||||
])
|
||||
];
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="openLoansColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: openLoansColumns;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: openLoansColumns;" [routerLink]="['/loans', row.id, 'general']" class="select-row"></tr>
|
||||
</table>
|
||||
|
||||
<!-- Closed Loan Accounts -->
|
||||
|
||||
@@ -18,5 +18,10 @@
|
||||
margin: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.select-row:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/** Custom Services */
|
||||
import { LoansService } from '../loans.service';
|
||||
|
||||
/**
|
||||
* Clients data resolver.
|
||||
*/
|
||||
@Injectable()
|
||||
export class LoanDetailsGeneralResolver implements Resolve<Object> {
|
||||
|
||||
/**
|
||||
* @param {LoansService} LoansService Loans service.
|
||||
*/
|
||||
constructor(private loansService: LoansService) { }
|
||||
|
||||
/**
|
||||
* Returns the Loans data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const loanId = route.parent.paramMap.get('loanId');
|
||||
return this.loansService.getLoanAccountDetails(loanId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/** Custom Services */
|
||||
import { LoansService } from '../loans.service';
|
||||
|
||||
/**
|
||||
* Clients data resolver.
|
||||
*/
|
||||
@Injectable()
|
||||
export class LoanDetailsResolver implements Resolve<Object> {
|
||||
|
||||
/**
|
||||
* @param {LoansService} LoansService Loans service.
|
||||
*/
|
||||
constructor(private loansService: LoansService) { }
|
||||
|
||||
/**
|
||||
* Returns the Loans data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const loanId = route.paramMap.get('loanId');
|
||||
return this.loansService.getLoanAccountDetails(loanId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,9 +7,14 @@ import { extract } from '../core/i18n/i18n.service';
|
||||
|
||||
/** Custom Components */
|
||||
import { AddLoanChargeComponent } from './add-loan-charge/add-loan-charge.component';
|
||||
import { LoansViewComponent } from './loans-view/loans-view.component';
|
||||
import { GeneralTabComponent } from './loans-view/general-tab/general-tab.component';
|
||||
import { AccountDetailsComponent } from './loans-view/account-details/account-details.component';
|
||||
|
||||
/** Custom Resolvers */
|
||||
import { LoanChargeTemplateResolver } from './common-resolvers/loan-charge-template.resolver';
|
||||
import { LoanDetailsResolver } from './common-resolvers/loan-details.resolver';
|
||||
import { LoanDetailsGeneralResolver } from './common-resolvers/loan-details-general.resolver';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -18,8 +23,28 @@ const routes: Routes = [
|
||||
children: [{
|
||||
path: ':loanId',
|
||||
data: { title: extract('Loan View'), routeParamBreadcrumb: 'loanId' },
|
||||
component: LoansViewComponent,
|
||||
resolve: {
|
||||
loanDetailsData: LoanDetailsResolver
|
||||
},
|
||||
// Component For Loan View Comes Here
|
||||
children: [
|
||||
{
|
||||
path: 'general',
|
||||
component: GeneralTabComponent,
|
||||
data: { title: extract('General'), breadcrumb: 'General', routeParamBreadcrumb: false },
|
||||
resolve: {
|
||||
loanDetailsData: LoanDetailsGeneralResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'accountdetail',
|
||||
component: AccountDetailsComponent,
|
||||
data: { title: extract('Account Detail'), breadcrumb: 'Account Detail', routeParamBreadcrumb: false },
|
||||
resolve: {
|
||||
loanDetailsData: LoanDetailsGeneralResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'add-loan-charge',
|
||||
component: AddLoanChargeComponent,
|
||||
@@ -36,6 +61,11 @@ const routes: Routes = [
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
declarations: [],
|
||||
providers: [LoanChargeTemplateResolver]
|
||||
providers: [
|
||||
LoanChargeTemplateResolver,
|
||||
LoanDetailsGeneralResolver,
|
||||
LoanDetailsResolver
|
||||
]
|
||||
})
|
||||
|
||||
export class LoansRoutingModule { }
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<div class="container">
|
||||
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%">Repayment Strategy:</span>
|
||||
<span fxFlex="50%">{{ loanDetails.transactionProcessingStrategyName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%">Repayments:</span>
|
||||
<span fxFlex="50%">{{loanDetails.numberOfRepayments}} every {{loanDetails.repaymentEvery}} {{loanDetails.repaymentFrequencyType.value}}
|
||||
<span *ngIf="loanDetails.repaymentFrequencyType?.id == 2 && loanDetails.repaymentFrequencyNthDayType?.id != 0 && loanDetails.repaymentFrequencyDayOfWeekType?.id != 0">
|
||||
on {{loanDetails.repaymentFrequencyNthDayType?.value}} {{loanDetails.repaymentFrequencyDayOfWeekType?.value}}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Amortization </span>
|
||||
<span fxFlex="50%"> {{loanDetails.amortizationType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Equal Amortization </span>
|
||||
<span fxFlex="50%"> {{loanDetails.isEqualAmortization}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Interest </span>
|
||||
<span fxFlex="50%"> {{loanDetails.annualInterestRate}} per annum ({{loanDetails.interestRatePerPeriod}}% {{loanDetails.interestRateFrequencyType.value}}) - {{loanDetails.interestType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Grace: On Principal Payment</span>
|
||||
<span fxFlex="50%"> {{loanDetails.graceOnPrincipalPayment}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Grace: On Interest Payment</span>
|
||||
<span fxFlex="50%"> {{loanDetails.graceOnInterestPayment}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Grace on Arrears Ageing</span>
|
||||
<span fxFlex="50%"> {{loanDetails.graceOnArrearsAgeing}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Fund Source</span>
|
||||
<span fxFlex="50%"> {{loanDetails.fundName}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Interest Free Period</span>
|
||||
<span fxFlex="50%"> {{loanDetails.graceOnInterestCharged}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Interest Calculation Period</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestCalculationPeriodType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Allow Partial Interest Calculation with same as repayment</span>
|
||||
<span fxFlex="50%"> {{loanDetails.allowPartialPeriodInterestCalcualtion}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Interest Type</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Submitted on</span>
|
||||
<span fxFlex="50%"> {{loanDetails.timeline.submittedOnDate | date }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Approved on</span>
|
||||
<span fxFlex="50%"> {{loanDetails.timeline.approvedOnDate | date }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Disbursed on</span>
|
||||
<span fxFlex="50%"> {{loanDetails.timeline.actualDisbursementDate | date }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Matures on</span>
|
||||
<span fxFlex="50%"> {{loanDetails.timeline.expectedMaturityDate | date }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.canDefineInstallmentAmount">
|
||||
<span fxFlex="50%"> Fixed EMI amount</span>
|
||||
<span fxFlex="50%"> {{loanDetails.fixedEmiAmount | number}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isTopup">
|
||||
<span fxFlex="50%"> Is Topup Loan?</span>
|
||||
<span fxFlex="50%"> {{loanDetails.isTopup}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isTopup">
|
||||
<span fxFlex="50%"> Loan closed with Topup </span>
|
||||
<span fxFlex="50%"> <a href="#">{{loanDetails.closureLoanAccountNo}}</a> </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isTopup">
|
||||
<span fxFlex="50%"> Topup closure amount</span>
|
||||
<span fxFlex="50%"> {{loanDetails.topupAmount| number}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Recalculate Interest based on new terms</span>
|
||||
<span fxFlex="50%"> {{loanDetails.isInterestRecalculationEnabled ? 'Yes' : 'No' }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Days in year</span>
|
||||
<span fxFlex="50%"> {{loanDetails.daysInYearType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="50%"> Days in month</span>
|
||||
<span fxFlex="50%"> {{loanDetails.daysInMonthType.value }} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isInterestRecalculationEnabled">
|
||||
<span fxFlex="50%"> Interest recalculation compounding on</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestRecalculationData.interestRecalculationCompoundingType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isInterestRecalculationEnabled">
|
||||
<span fxFlex="50%"> Advance payments adjustment type</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestRecalculationData.rescheduleStrategyType.value}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isInterestRecalculationEnabled">
|
||||
<span fxFlex="50%"> Frequency for recalculate Outstanding Principal</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestRecalculationData.calendarData.humanReadable}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isInterestRecalculationEnabled && loanDetails.interestRecalculationData.interestRecalculationCompoundingType.id !=0">
|
||||
<span fxFlex="50%"> Frequency for compounding</span>
|
||||
<span fxFlex="50%"> {{loanDetails.interestRecalculationData.compoundingCalendarData.humanReadable}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isVariableInstallmentsAllowed">
|
||||
<span fxFlex="50%"> Variable Installments Allowed</span>
|
||||
<span fxFlex="50%"> {{loanDetails.isVariableInstallmentsAllowed}} </span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanDetails.isVariableInstallmentsAllowed">
|
||||
<span fxFlex="50%"> Gap between Installments:(Min</span>
|
||||
<span fxFlex="50%"> {{loanDetails.minimumGap}} Days , Max:{{loanDetails.maximumGap}} Days) </span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AccountDetailsComponent } from './account-details.component';
|
||||
|
||||
describe('AccountDetailsComponent', () => {
|
||||
let component: AccountDetailsComponent;
|
||||
let fixture: ComponentFixture<AccountDetailsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AccountDetailsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AccountDetailsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-account-details',
|
||||
templateUrl: './account-details.component.html',
|
||||
styleUrls: ['./account-details.component.scss']
|
||||
})
|
||||
export class AccountDetailsComponent implements OnInit {
|
||||
|
||||
loanDetails: any;
|
||||
dataObject: {
|
||||
property: string,
|
||||
value: string
|
||||
}[];
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { loanDetailsData: any, }) => {
|
||||
this.loanDetails = data.loanDetailsData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
export const ButtonConfig = {
|
||||
'Submitted and pending approval': {
|
||||
singlebuttons: [
|
||||
{
|
||||
name: 'Add Loan Charge',
|
||||
icon: 'fa fa-plus',
|
||||
taskPermissionName: 'CREATE_LOANCHARGE',
|
||||
},
|
||||
{
|
||||
name: 'Approve',
|
||||
icon: 'fa fa-check',
|
||||
taskPermissionName: 'APPROVE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Modify Application',
|
||||
icon: 'fa fa-pincel-square-o',
|
||||
taskPermissionName: 'UPDATE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Reject',
|
||||
icon: 'fa fa-times',
|
||||
taskPermissionName: 'REJECT_LOAN',
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Withdrawn by client',
|
||||
taskPermissionName: 'WITHDRAW_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
taskPermissionName: 'DELETE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Add Collateral',
|
||||
taskPermissionName: 'CREATE_COLLATERAL',
|
||||
},
|
||||
{
|
||||
name: 'View Guarantors',
|
||||
taskPermissionName: 'READ_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Create Guarantor',
|
||||
taskPermissionName: 'CREATE_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Loan Screen Reports',
|
||||
taskPermissionName: 'READ_LOAN',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Approved: {
|
||||
singlebuttons: [
|
||||
{
|
||||
name: 'Disburse',
|
||||
icon: 'fa fa-flag',
|
||||
taskPermissionName: 'DISBURSE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Disburse to Savings',
|
||||
icon: 'fa fa-flag',
|
||||
taskPermissionName: 'DISBURSETOSAVINGS_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Undo Approval',
|
||||
icon: 'fa fa-undo',
|
||||
taskPermissionName: 'APPROVALUNDO_LOAN',
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Add Loan Charge',
|
||||
taskPermissionName: 'CREATE_LOANCHARGE',
|
||||
},
|
||||
{
|
||||
name: 'List Guarantor',
|
||||
taskPermissionName: 'READ_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Create Guarantor',
|
||||
taskPermissionName: 'CREATE_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Loan Screen Report',
|
||||
taskPermissionName: 'READ_LOAN',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Active: {
|
||||
singlebuttons: [
|
||||
{
|
||||
name: 'Add Loan Charge',
|
||||
icon: 'fa fa-plus',
|
||||
taskPermissionName: 'CREATE_LOANCHARGE',
|
||||
},
|
||||
{
|
||||
name: 'Foreclosure',
|
||||
icon: 'icon-dollar',
|
||||
taskPermissionName: 'FORECLOSURE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Make Repayment',
|
||||
icon: 'fa fa-dollar',
|
||||
taskPermissionName: 'REPAYMENT_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Undo Disbursal',
|
||||
icon: 'fa fa-undo',
|
||||
taskPermissionName: 'DISBURSALUNDO_LOAN',
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'Waive Interest',
|
||||
taskPermissionName: 'WAIVEINTERESTPORTION_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Reschedule',
|
||||
taskPermissionName: 'CREATE_RESCHEDULELOAN',
|
||||
},
|
||||
{
|
||||
name: 'Write Off',
|
||||
taskPermissionName: 'WRITEOFF_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Close (as Rescheduled)',
|
||||
taskPermissionName: 'CLOSEASRESCHEDULED_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Close',
|
||||
taskPermissionName: 'CLOSE_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'Loan Screen Report',
|
||||
taskPermissionName: 'READ_LOAN',
|
||||
},
|
||||
{
|
||||
name: 'List Guarantor',
|
||||
taskPermissionName: 'READ_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Create Guarantor',
|
||||
taskPermissionName: 'CREATE_GUARANTOR',
|
||||
},
|
||||
{
|
||||
name: 'Recover Guarantee',
|
||||
taskPermissionName: 'RECOVERGUARANTEES_LOAN',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Overpaid: {
|
||||
singlebuttons: [
|
||||
{
|
||||
name: 'Transfer Funds',
|
||||
icon: 'fa fa-exchange',
|
||||
taskPermissionName: 'CREATE_ACCOUNTTRANSFER',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
'Closed (written off)': {
|
||||
singlebuttons: [
|
||||
{
|
||||
name: 'Recovery Payment',
|
||||
icon: 'fa fa-briefcase',
|
||||
taskPermissionName: 'RECOVERYPAYMENT_LOAN',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
@import "~@angular/material/theming";
|
||||
|
||||
@mixin loans-view-component-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
|
||||
mifosx-loans-view {
|
||||
.loan-card {
|
||||
.header {
|
||||
background-color: mat-color($primary, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<mat-card class="loan-card">
|
||||
<mat-card-header fxLayout="column" class="header">
|
||||
|
||||
<mat-card-title-group class="header-title-group">
|
||||
<div class="mat-typography loan-card-title">
|
||||
<mat-card-title>
|
||||
<div fxLayout="row" fxLayout.lt-md="column">
|
||||
<div fxFlex="50%">
|
||||
<h3>
|
||||
<i class="fa fa-stop" matTooltip="{{ loanDetailsData.status.value }}" [ngClass]="loanDetailsData.inArrears?'status-active-overdue':(loanDetailsData.status.code|statusLookup)"></i>
|
||||
Loan Product: {{loanDetailsData.loanProductName}}(#{{loanDetailsData.accountNo}})
|
||||
<br/>
|
||||
<span *ngIf="loanDetailsData.clientName" > Client Name: {{loanDetailsData.clientName}} </span> <br/>
|
||||
<span *ngIf="loanDetailsData.group" > Group Name: {{loanDetailsData.group.name}} </span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanDetailsData.summary" class="loansOverview mat-typography" fxFlex="50%">
|
||||
<h3> Loan Account OverView </h3>
|
||||
<span>Current Balance: {{loanDetailsData.currency.displaySymbol}} {{loanDetailsData.summary.totalOutstanding | number}}</span><br>
|
||||
<span>Arrears By: {{loanDetailsData.summary.totalOverdue | number}}
|
||||
<span *ngIf="!(loanDetailsData.summary.totalOverdue>=0)">Not Provided</span>
|
||||
</span><br>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-title>
|
||||
</div>
|
||||
</mat-card-title-group>
|
||||
|
||||
<mat-card-actions class="loan-actions">
|
||||
|
||||
<ng-container *ngFor="let item of buttons.singlebuttons" class="loan-span">
|
||||
<button mat-raised-button *mifosxHasPermission="item.taskPermissionName">
|
||||
<i class="{{item.icon}}"></i> {{item.name}} </button>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!(buttons.options === undefined)" class="loan-span">
|
||||
<button mat-raised-button [matMenuTriggerFor]="More">More</button>
|
||||
<mat-menu #More="matMenu">
|
||||
<span *ngFor="let item of buttons.options">
|
||||
<button mat-menu-item *mifosxHasPermission="item.taskPermissionName">{{item.name}}</button>
|
||||
</span>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
|
||||
</mat-card-actions>
|
||||
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
<nav mat-tab-nav-bar class="navigation-tabs">
|
||||
<a mat-tab-link [routerLink]="['./general']" routerLinkActive #general="routerLinkActive" [active]="general.isActive">
|
||||
General
|
||||
</a>
|
||||
<a mat-tab-link [routerLink]="['./accountdetail']" routerLinkActive #accountdetail="routerLinkActive" [active]="accountdetail.isActive">
|
||||
Account Details
|
||||
</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
@@ -0,0 +1,33 @@
|
||||
.loan-card {
|
||||
margin: 0 auto;
|
||||
max-width: 80rem;
|
||||
width: 90%;
|
||||
padding: 0;
|
||||
.header {
|
||||
padding: 1%;
|
||||
.header-title-group {
|
||||
.loan-card-title {
|
||||
color: white;
|
||||
width: 90%;
|
||||
p {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
.loan-actions {
|
||||
align-self: flex-end;
|
||||
margin: 0 1%;
|
||||
// min-width: 72%;
|
||||
}
|
||||
.loan-span {
|
||||
margin: 0 0.5%;
|
||||
}
|
||||
}
|
||||
.navigation-tabs {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.loansOverview{
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoansViewComponent } from './loans-view.component';
|
||||
|
||||
describe('LoansViewComponent', () => {
|
||||
let component: LoansViewComponent;
|
||||
let fixture: ComponentFixture<LoansViewComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LoansViewComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoansViewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,111 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { LoansService } from '../loans.service';
|
||||
|
||||
// Custom Imports
|
||||
import { ButtonConfig } from './button-config';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loans-view',
|
||||
templateUrl: './loans-view.component.html',
|
||||
styleUrls: ['./loans-view.component.scss']
|
||||
})
|
||||
export class LoansViewComponent implements OnInit {
|
||||
|
||||
loanDetailsData: any;
|
||||
recalculateInterest: any;
|
||||
status: string;
|
||||
buttons: {
|
||||
singlebuttons: {
|
||||
name: string,
|
||||
icon: string,
|
||||
taskPermissionName: string,
|
||||
}[],
|
||||
options?: {
|
||||
name: string,
|
||||
taskPermissionName: string
|
||||
}[]
|
||||
};
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { loanDetailsData: any, }) => {
|
||||
this.loanDetailsData = data.loanDetailsData;
|
||||
console.log('loandata:: ', this.loanDetailsData);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.recalculateInterest = this.loanDetailsData.recalculateInterest || true;
|
||||
this.status = this.loanDetailsData.status.value;
|
||||
|
||||
console.log('status: ', this.status);
|
||||
// Defines the buttons based on the status of the loan account
|
||||
if (this.status === 'Submitted and pending approval') {
|
||||
this.buttons = ButtonConfig['Submitted and pending approval'];
|
||||
|
||||
this.buttons.options.splice(1, 0, {
|
||||
name: (this.loanDetailsData.loanOfficerName ? 'Change Loan Officer' : 'Assign Loan Officer' ),
|
||||
taskPermissionName: 'DISBURSE_LOAN'
|
||||
});
|
||||
|
||||
if (this.loanDetailsData.isVariableInstallmentsAllowed) {
|
||||
this.buttons.options.push({
|
||||
name: 'Edit Repayment Schedule',
|
||||
taskPermissionName: 'ADJUST_REPAYMENT_SCHEDULE'
|
||||
}) ;
|
||||
}
|
||||
|
||||
} else if (this.status === 'Approved') {
|
||||
this.buttons = ButtonConfig['Approved'];
|
||||
|
||||
this.buttons.singlebuttons.splice(1, 0, {
|
||||
name: (this.loanDetailsData.loanOfficerName ? 'Change Loan Officer' : 'Assign Loan Officer' ),
|
||||
icon: 'fa fa-user',
|
||||
taskPermissionName: 'DISBURSE_LOAN'
|
||||
});
|
||||
|
||||
} else if (this.status === 'Active') {
|
||||
this.buttons = ButtonConfig['Active'];
|
||||
|
||||
if (this.loanDetailsData.canDisburse) {
|
||||
this.buttons.singlebuttons.splice(1, 0, {
|
||||
name: 'Disburse',
|
||||
icon: 'fa fa-flag',
|
||||
taskPermissionName: 'DISBURSE_LOAN'
|
||||
});
|
||||
this.buttons.singlebuttons.splice(1, 0, {
|
||||
name: 'Disburse To Savings',
|
||||
icon: 'fa fa-flag',
|
||||
taskPermissionName: 'DISBURSETOSAVINGS_LOAN'
|
||||
});
|
||||
}
|
||||
|
||||
// loan officer not assigned to loan, below logic
|
||||
// helps to display otherwise not
|
||||
if (!this.loanDetailsData.loanOfficerName) {
|
||||
this.buttons.singlebuttons.splice(1, 0, {
|
||||
name: 'Assign Loan Officer',
|
||||
icon: 'fa fa-user',
|
||||
taskPermissionName: 'UPDATELOANOFFICER_LOAN'
|
||||
});
|
||||
}
|
||||
|
||||
if (this.recalculateInterest) {
|
||||
this.buttons.singlebuttons.splice(1, 0, {
|
||||
name: 'Prepay Loan',
|
||||
icon: 'fa fa-money',
|
||||
taskPermissionName: 'REPAYMENT_LOAN'
|
||||
});
|
||||
}
|
||||
|
||||
} else if (this.status === 'Overpaid') {
|
||||
this.buttons = ButtonConfig['Overpaid'];
|
||||
} else if (this.status === 'Closed (written off)') {
|
||||
this.buttons = ButtonConfig['Closed (written off)'];
|
||||
}
|
||||
console.log('this.buttons: ', this.buttons);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
/** Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { DatePipe} from '@angular/common';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { DirectivesModule } from '../directives/directives.module';
|
||||
|
||||
/** Custom Modules */
|
||||
import { LoansRoutingModule } from './loans-routing.module';
|
||||
import { SharedModule } from 'app/shared/shared.module';
|
||||
import { PipesModule } from '../pipes/pipes.module';
|
||||
|
||||
/** Custom Components */
|
||||
import { AddLoanChargeComponent } from './add-loan-charge/add-loan-charge.component';
|
||||
import { LoansViewComponent } from './loans-view/loans-view.component';
|
||||
import { GeneralTabComponent } from './loans-view/general-tab/general-tab.component';
|
||||
import { AccountDetailsComponent } from './loans-view/account-details/account-details.component';
|
||||
|
||||
/**
|
||||
* Loans Module
|
||||
@@ -15,12 +20,13 @@ import { AddLoanChargeComponent } from './add-loan-charge/add-loan-charge.compon
|
||||
* All components related to loan functions should be declared here.
|
||||
*/
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
LoansRoutingModule
|
||||
imports: [SharedModule, LoansRoutingModule, DirectivesModule, PipesModule],
|
||||
declarations: [
|
||||
AddLoanChargeComponent,
|
||||
LoansViewComponent,
|
||||
GeneralTabComponent,
|
||||
AccountDetailsComponent,
|
||||
],
|
||||
declarations: [AddLoanChargeComponent],
|
||||
providers: [DatePipe]
|
||||
|
||||
providers: [DatePipe],
|
||||
})
|
||||
export class LoansModule { }
|
||||
export class LoansModule {}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Observable } from 'rxjs';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LoansService {
|
||||
constructor(private http: HttpClient) {}
|
||||
constructor(private http: HttpClient) { }
|
||||
/**
|
||||
* @param {string} loanId loanId of the loan.
|
||||
* @returns {Observable<any>}
|
||||
@@ -29,4 +29,8 @@ export class LoansService {
|
||||
return this.http.post(`/loans/${loanId}/${resourceType}`, loanCharge);
|
||||
}
|
||||
|
||||
getLoanAccountDetails(loanId: string) {
|
||||
return this.http.get(`/loans/${loanId}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
@import '../../app/groups/groups-view/groups-view.component-theme.scss';
|
||||
@import '../../app/centers/centers-view/centers-view.component-theme.scss';
|
||||
@import '../../app/home/dashboard/dashboard.component-theme.scss';
|
||||
@import '../../app/loans/loans-view/loans-view.component-theme.scss';
|
||||
|
||||
// Custom material palette
|
||||
$mat-denim: (
|
||||
@@ -53,3 +54,4 @@ $mifosx-app-theme: mat-light-theme($mifosx-app-primary, $mifosx-app-accent, $mif
|
||||
@include groups-view-component-theme($mifosx-app-theme);
|
||||
@include centers-view-component-theme($mifosx-app-theme);
|
||||
@include dashboard-component-theme($mifosx-app-theme);
|
||||
@include loans-view-component-theme($mifosx-app-theme);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
@import '../../app/groups/groups-view/groups-view.component-theme.scss';
|
||||
@import '../../app/centers/centers-view/centers-view.component-theme.scss';
|
||||
@import '../../app/home/dashboard/dashboard.component-theme.scss';
|
||||
@import '../../app/loans/loans-view/loans-view.component-theme.scss';
|
||||
|
||||
// Custom material palette
|
||||
$mat-picton-blue: (
|
||||
@@ -53,3 +54,4 @@ $mifosx-app-theme: mat-light-theme($mifosx-app-primary, $mifosx-app-accent, $mif
|
||||
@include groups-view-component-theme($mifosx-app-theme);
|
||||
@include centers-view-component-theme($mifosx-app-theme);
|
||||
@include dashboard-component-theme($mifosx-app-theme);
|
||||
@include loans-view-component-theme($mifosx-app-theme);
|
||||
|
||||
Reference in New Issue
Block a user