Datatables enhacements to support products (#1641)
Co-authored-by: Jose Alberto Hernandez <alberto@MacBook-Pro.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
08a327fdbf
commit
f330e91aa4
@@ -84,6 +84,14 @@
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step *ngFor="let datatable of datatables">
|
||||
|
||||
<ng-template matStepLabel>{{datatable.registeredTableName}}</ng-template>
|
||||
|
||||
<mifosx-loan-product-datatable-step [datatableData]="datatable" #dtloanproduct></mifosx-loan-product-datatable-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step state="preview" *ngIf="loanProductFormValid" completed>
|
||||
|
||||
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||
|
||||
+28
-4
@@ -1,5 +1,5 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Component, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
/** Custom Components */
|
||||
@@ -13,6 +13,7 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan
|
||||
/** Custom Services */
|
||||
import { ProductsService } from 'app/products/products.service';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
import { LoanProductDatatableStepComponent } from '../loan-product-stepper/loan-product-datatable-step/loan-product-datatable-step.component';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-create-loan-product',
|
||||
@@ -27,6 +28,10 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
@ViewChild(LoanProductSettingsStepComponent, { static: true }) loanProductSettingsStep: LoanProductSettingsStepComponent;
|
||||
@ViewChild(LoanProductChargesStepComponent, { static: true }) loanProductChargesStep: LoanProductChargesStepComponent;
|
||||
@ViewChild(LoanProductAccountingStepComponent, { static: true }) loanProductAccountingStep: LoanProductAccountingStepComponent;
|
||||
/** Get handle on dtloanproduct tags in the template */
|
||||
@ViewChildren('dtloanproduct') loanProductDatatables: QueryList<LoanProductDatatableStepComponent>;
|
||||
|
||||
datatables: any = [];
|
||||
|
||||
loanProductsTemplate: any;
|
||||
accountingRuleData = ['None', 'Cash', 'Accrual (periodic)', 'Accrual (upfront)'];
|
||||
@@ -42,8 +47,10 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
private productsService: ProductsService,
|
||||
private settingsService: SettingsService,
|
||||
private router: Router) {
|
||||
this.route.data.subscribe((data: { loanProductsTemplate: any }) => {
|
||||
this.route.data.subscribe((data: { loanProductsTemplate: any, loanProductDatatables: any }) => {
|
||||
this.loanProductsTemplate = data.loanProductsTemplate;
|
||||
// this.datatables = data.loanProductDatatables;
|
||||
this.datatables = [];
|
||||
const assetAccountData = this.loanProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||
const liabilityAccountData = this.loanProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
||||
@@ -74,13 +81,21 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
}
|
||||
|
||||
get loanProductFormValid() {
|
||||
return (
|
||||
let areValids = (
|
||||
this.loanProductDetailsForm.valid &&
|
||||
this.loanProductCurrencyForm.valid &&
|
||||
this.loanProductTermsForm.valid &&
|
||||
this.loanProductSettingsForm.valid &&
|
||||
this.loanProductAccountingForm.valid
|
||||
);
|
||||
|
||||
if (this.datatables.length > 0 && this.loanProductDatatables) {
|
||||
this.loanProductDatatables.forEach((loanProductDatatable: LoanProductDatatableStepComponent) => {
|
||||
areValids = areValids && loanProductDatatable.datatableForm.valid;
|
||||
});
|
||||
}
|
||||
|
||||
return areValids;
|
||||
}
|
||||
|
||||
get loanProduct() {
|
||||
@@ -95,7 +110,6 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
}
|
||||
|
||||
submit() {
|
||||
// TODO: Update once language and date settings are setup
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const loanProduct = {
|
||||
...this.loanProduct,
|
||||
@@ -105,6 +119,16 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
};
|
||||
delete loanProduct.allowAttributeConfiguration;
|
||||
delete loanProduct.advancedAccountingRules;
|
||||
|
||||
if (this.datatables.length > 0) {
|
||||
const datatables: any[] = [];
|
||||
this.loanProductDatatables.forEach((loanProductDatatable: LoanProductDatatableStepComponent) => {
|
||||
datatables.push(loanProductDatatable.payload);
|
||||
});
|
||||
loanProduct['datatables'] = datatables;
|
||||
}
|
||||
|
||||
|
||||
this.productsService.createLoanProduct(loanProduct)
|
||||
.subscribe((response: any) => {
|
||||
this.router.navigate(['../', response.resourceId], { relativeTo: this.route });
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ export class LoanProductAndTemplateResolver implements Resolve<Object> {
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const loanProductId = route.paramMap.get('id');
|
||||
const loanProductId = route.paramMap.get('productId');
|
||||
return this.productsService.getLoanProduct(loanProductId, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoanProductDatatableResolver } from './loan-product-datatable.resolver';
|
||||
|
||||
describe('LoanProductDatatableResolver', () => {
|
||||
let resolver: LoanProductDatatableResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
resolver = TestBed.inject(LoanProductDatatableResolver);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(resolver).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LoanProductDatatableResolver implements Resolve<boolean> {
|
||||
|
||||
/**
|
||||
* @param {SystemService} systemService Products service.
|
||||
*/
|
||||
constructor(private systemService: SystemService) { }
|
||||
|
||||
/**
|
||||
* Returns the loan product data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const productId = route.parent.parent.paramMap.get('productId');
|
||||
const datatableName = route.paramMap.get('datatableName');
|
||||
return this.systemService.getEntityDatatable(productId, datatableName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoanProductDatatablesResolver } from './loan-product-datatables.resolver';
|
||||
|
||||
describe('LoanProductDatatablesResolver', () => {
|
||||
let resolver: LoanProductDatatablesResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
resolver = TestBed.inject(LoanProductDatatablesResolver);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(resolver).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LoanProductDatatablesResolver implements Resolve<boolean> {
|
||||
|
||||
/**
|
||||
* @param {SystemService} systemService Products service.
|
||||
*/
|
||||
constructor(private systemService: SystemService) { }
|
||||
|
||||
/**
|
||||
* Returns the loan product data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
return this.systemService.getEntityDatatables('m_product_loan');
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<form [formGroup]="datatableForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<div *ngFor="let datatableInput of datatableInputs" fxFlex="48%">
|
||||
<mat-form-field fxFlex="100%" *ngIf="!isBoolean(datatableInput.columnDisplayType)">
|
||||
|
||||
<mat-label>{{getInputName(datatableInput)}}</mat-label>
|
||||
|
||||
<mat-select *ngIf="isDropdown(datatableInput.columnDisplayType)" formControlName="{{datatableInput.controlName}}">
|
||||
<mat-option *ngFor="let code of datatableInput.columnValues" [value]="code.id">
|
||||
{{ code.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
<input matInput type="number" *ngIf="isNumeric(datatableInput.columnDisplayType)"
|
||||
formControlName="{{datatableInput.controlName}}">
|
||||
|
||||
<input matInput *ngIf="isString(datatableInput.columnDisplayType)"
|
||||
formControlName="{{datatableInput.controlName}}">
|
||||
|
||||
<textarea matInput *ngIf="isText(datatableInput.columnDisplayType)"
|
||||
formControlName="{{datatableInput.controlName}}"></textarea>
|
||||
|
||||
<span *ngIf="isDate(datatableInput.columnDisplayType)" (click)="datePicker.open()">
|
||||
<input matInput [matDatepicker]="datePicker" formControlName="{{datatableInput.controlName}}" class="date-picker">
|
||||
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #datePicker></mat-datepicker>
|
||||
</span>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox *ngIf="isBoolean(datatableInput.columnDisplayType)" formControlName="{{datatableInput.controlName}}"
|
||||
labelPosition="before" class="margin-v">
|
||||
{{getInputName(datatableInput)}}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious disabled>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext>
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
.date-picker {
|
||||
width: 92%;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
margin-top: 30px;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoanProductDatatableStepComponent } from './loan-product-datatable-step.component';
|
||||
|
||||
describe('LoanProductDatatableStepComponent', () => {
|
||||
let component: LoanProductDatatableStepComponent;
|
||||
let fixture: ComponentFixture<LoanProductDatatableStepComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ LoanProductDatatableStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoanProductDatatableStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { Datatables } from 'app/core/utils/datatables';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-loan-product-datatable-step',
|
||||
templateUrl: './loan-product-datatable-step.component.html',
|
||||
styleUrls: ['./loan-product-datatable-step.component.scss']
|
||||
})
|
||||
export class LoanProductDatatableStepComponent implements OnInit {
|
||||
/** Input Fields Data */
|
||||
@Input() datatableData: any;
|
||||
/** Create Input Form */
|
||||
datatableForm: FormGroup;
|
||||
|
||||
datatableInputs: any = [];
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
private settingsService: SettingsService,
|
||||
private datatableService: Datatables) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.datatableInputs = this.datatableService.filterSystemColumns(this.datatableData.columnHeaderData);
|
||||
const inputItems: any = {};
|
||||
this.datatableInputs.forEach((input: any) => {
|
||||
input.controlName = this.getInputName(input);
|
||||
if (!input.isColumnNullable) {
|
||||
if (this.isNumeric(input.columnDisplayType)) {
|
||||
inputItems[input.controlName] = new FormControl(0, [Validators.required]);
|
||||
} else {
|
||||
inputItems[input.controlName] = new FormControl('', [Validators.required]);
|
||||
}
|
||||
} else {
|
||||
inputItems[input.controlName] = new FormControl('');
|
||||
}
|
||||
});
|
||||
this.datatableForm = this.formBuilder.group(inputItems);
|
||||
}
|
||||
|
||||
getInputName(datatableInput: any): string {
|
||||
return this.datatableService.getInputName(datatableInput);
|
||||
}
|
||||
|
||||
isNumeric(columnType: string) {
|
||||
return this.datatableService.isNumeric(columnType);
|
||||
}
|
||||
|
||||
isDate(columnType: string) {
|
||||
return this.datatableService.isDate(columnType);
|
||||
}
|
||||
|
||||
isBoolean(columnType: string) {
|
||||
return this.datatableService.isBoolean(columnType);
|
||||
}
|
||||
|
||||
isDropdown(columnType: string) {
|
||||
return this.datatableService.isDropdown(columnType);
|
||||
}
|
||||
|
||||
isString(columnType: string) {
|
||||
return this.datatableService.isString(columnType);
|
||||
}
|
||||
|
||||
isText(columnType: string) {
|
||||
return this.datatableService.isText(columnType);
|
||||
}
|
||||
|
||||
get payload(): any {
|
||||
const dateFormat = this.settingsService.dateFormat;
|
||||
const datatableDataValues = this.datatableForm.value;
|
||||
|
||||
const data = this.datatableService.buildPayload(this.datatableInputs, datatableDataValues, dateFormat,
|
||||
{ locale: this.settingsService.language.code });
|
||||
|
||||
return {
|
||||
registeredTableName: this.datatableData.registeredTableName,
|
||||
data: data
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+1
-2
@@ -84,8 +84,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
'holdGuaranteeFunds': this.loanProductsTemplate.holdGuaranteeFunds,
|
||||
'multiDisburseLoan': this.loanProductsTemplate.multiDisburseLoan,
|
||||
'maxTrancheCount': this.loanProductsTemplate.maxTrancheCount,
|
||||
'outstandingLoanBalance': this.loanProductsTemplate.outstandingLoanBalance,
|
||||
'delinquencyBucketId': this.loanProductsTemplate.delinquencyBucket.id
|
||||
'outstandingLoanBalance': this.loanProductsTemplate.outstandingLoanBalance
|
||||
});
|
||||
|
||||
if (this.loanProductsTemplate.isInterestRecalculationEnabled) {
|
||||
|
||||
@@ -24,8 +24,8 @@ export class LoanProductResolver implements Resolve<Object> {
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const id = route.paramMap.get('id');
|
||||
return this.productsService.getLoanProduct(id);
|
||||
const productId = route.parent.paramMap.get('productId');
|
||||
return this.productsService.getLoanProduct(productId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<div class="tab-container mat-typography">
|
||||
<mifosx-entity-datatable-tab
|
||||
entityType="Loan Product"
|
||||
[entityId]="entityId"
|
||||
[multiRowDatatableFlag]="multiRowDatatableFlag"
|
||||
[entityDatatable]="entityDatatable"
|
||||
>
|
||||
</mifosx-entity-datatable-tab>
|
||||
</div>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DatatableTabComponent } from './datatable-tab.component';
|
||||
|
||||
describe('DatatableTabComponent', () => {
|
||||
let component: DatatableTabComponent;
|
||||
let fixture: ComponentFixture<DatatableTabComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DatatableTabComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DatatableTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-datatable-tab',
|
||||
templateUrl: './datatable-tab.component.html',
|
||||
styleUrls: ['./datatable-tab.component.scss']
|
||||
})
|
||||
export class DatatableTabComponent implements OnInit {
|
||||
entityId: string;
|
||||
entityDatatable: any;
|
||||
multiRowDatatableFlag: boolean;
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.entityId = this.route.parent.parent.snapshot.paramMap.get('productId');
|
||||
|
||||
this.route.data.subscribe((data: { loanProductDatatable: any }) => {
|
||||
this.entityDatatable = data.loanProductDatatable;
|
||||
this.multiRowDatatableFlag = this.entityDatatable.columnHeaders[0].columnName === 'id' ? true : false;
|
||||
});
|
||||
|
||||
}
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
+799
@@ -0,0 +1,799 @@
|
||||
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_LOANPRODUCT'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>Edit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tab-container mat-typography">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Name:</span>
|
||||
<span fxFlex="60%"><b>{{ loanProduct.name }}</b></span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Short Name:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.shortName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.fundId">
|
||||
<span fxFlex="40%">Fund Name:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.fundName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Include in Customer Loan Counter:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.includeInBorrowerCycle ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.startDate">
|
||||
<span fxFlex="40%">Start Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.startDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.closeDate">
|
||||
<span fxFlex="40%">Close Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.closeDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.description }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Decimal Places:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.decimalPlaces }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency in multiples of:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.inMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Installment in multiples of:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.installmentAmountInMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Principal:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.principal | number }}
|
||||
(Min {{ (loanProduct.minPrincipal ? loanProduct.minPrincipal : loanProduct.principal) | number }}
|
||||
: Max {{ (loanProduct.maxPrincipal ? loanProduct.maxPrincipal : loanProduct.principal) | number }})
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow Approved / Disbursed Amounts Over Applied:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowApprovedDisbursedAmountsOverApplied ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowApprovedDisbursedAmountsOverApplied">
|
||||
<span fxFlex="40%">Over Applied Amount:</span>
|
||||
<span fxFlex="60%" *ngIf="loanProduct.overAppliedCalculationType === 'percentage'">{{ loanProduct.overAppliedNumber | number
|
||||
}} %</span>
|
||||
<span fxFlex="60%" *ngIf="loanProduct.overAppliedCalculationType === 'flat'">{{ loanProduct.overAppliedNumber | number }} {{
|
||||
loanProduct.currencyCode }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Number of Repayments:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.numberOfRepayments + ' (Min: ' + (loanProduct.minNumberOfRepayments ?
|
||||
loanProduct.minNumberOfRepayments : loanProduct.numberOfRepayments) + ', Max: ' +
|
||||
(loanProduct.maxNumberOfRepayments ? loanProduct.maxNumberOfRepayments : loanProduct.numberOfRepayments) + ')'
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Linked to floating interest rates:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isLinkedToFloatingInterestRates ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="!loanProduct.isLinkedToFloatingInterestRates">
|
||||
<span fxFlex="40%">Nominal interest rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRatePerPeriod + ' (Min: ' + (loanProduct.minInterestRatePerPeriod ?
|
||||
loanProduct.minInterestRatePerPeriod : loanProduct.interestRatePerPeriod) + ', Max: ' +
|
||||
(loanProduct.maxInterestRatePerPeriod ? loanProduct.maxInterestRatePerPeriod : loanProduct.interestRatePerPeriod)
|
||||
+ ')' + ' ' + loanProduct.interestRateFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.isLinkedToFloatingInterestRates" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Floating Lending Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.floatingRateName }}</span>
|
||||
<span fxFlex="40%">Interest Rate Differential:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRateDifferential }}</span>
|
||||
<span fxFlex="40%">Floating Interest Rate Calculation Allowed:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isFloatingInterestRateCalculationAllowed ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Floating Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.defaultDifferentialLendingRate + ' (Min: ' +
|
||||
(loanProduct.minDifferentialLendingRate ? loanProduct.minDifferentialLendingRate :
|
||||
loanProduct.defaultDifferentialLendingRate) + ', Max: ' + (loanProduct.maxDifferentialLendingRate ?
|
||||
loanProduct.maxDifferentialLendingRate : loanProduct.defaultDifferentialLendingRate) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Terms vary based on loan cycle:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.useBorrowerCycle ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.principalVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Principal by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.principalVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.numberOfRepaymentVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Number of Repayments by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table
|
||||
[dataSource]="loanProduct.numberOfRepaymentVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRateVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Nominal Interest Rate by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table
|
||||
[dataSource]="loanProduct.interestRateVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Repay Every:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.repaymentEvery + ' ' + loanProduct.repaymentFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.minimumDaysBetweenDisbursalAndFirstRepayment">
|
||||
<span fxFlex="40%">Minimum days between disbursal and first repayment date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.minimumDaysBetweenDisbursalAndFirstRepayment }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.amortizationType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Equal Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isEqualAmortization ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Method:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Calculation Period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestCalculationPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.interestCalculationPeriodType.id === 1">
|
||||
<span fxFlex="40%">Allow Partial Interest Calculation with same as repayment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowPartialPeriodInterestCalcualtion ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Repayment Strategy:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.transactionProcessingStrategyName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnPrincipalPayment">
|
||||
<span fxFlex="40%">Grace on principal payment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnPrincipalPayment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnInterestPayment">
|
||||
<span fxFlex="40%">Grace on interest payment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnInterestPayment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnInterestCharged">
|
||||
<span fxFlex="40%">Interest free period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnInterestCharged }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.inArrearsTolerance">
|
||||
<span fxFlex="40%">Arrears tolerance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.inArrearsTolerance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in year:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.daysInYearType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in month:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.daysInMonthType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow fixing of the installment amount:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.canDefineInstallmentAmount ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnArrearsAgeing">
|
||||
<span fxFlex="40%">Number of days a loan may be overdue before moving into arrears:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnArrearsAgeing }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.overdueDaysForNPA">
|
||||
<span fxFlex="40%">Maximum number of days a loan may be overdue before becoming a NPA (non performing asset):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.overdueDaysForNPA }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Account moves out of NPA only after all arrears have been cleared:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.accountMovesOutOfNPAOnlyOnArrearsCompletion ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.principalThresholdForLastInstallment">
|
||||
<span fxFlex="40%">Principal Threshold (%) for Last Instalment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.principalThresholdForLastInstallment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Variable Installments allowed:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowVariableInstallments ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowVariableInstallments">
|
||||
<span fxFlex="40%">Variable Installments:</span>
|
||||
<span fxFlex="60%">{{ '(Min: ' + loanProduct.minimumGap + ', Max: ' + (loanProduct.maximumGap ?
|
||||
loanProduct.maximumGap : loanProduct.minimumGap) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allowed to be used for providing Topup Loans:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.canUseForTopup ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Interest Recalculation</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Recalculate Interest:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isInterestRecalculationEnabled ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.isInterestRecalculationEnabled" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Pre-closure interest calculation rule:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.preClosureInterestCalculationStrategy.value }}</span>
|
||||
<span fxFlex="40%">Advance payments adjustment type:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.rescheduleStrategyType.value }}</span>
|
||||
<span fxFlex="40%">Interest recalculation compounding on:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.interestRecalculationCompoundingType.value }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.interestRecalculationCompoundingType.id !== 0"
|
||||
fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency for compounding:</span>
|
||||
<span fxFlex="60%">
|
||||
{{ loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.value }}
|
||||
<span
|
||||
*ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationCompoundingFrequencyNthDay"> {{
|
||||
'on ' + loanProduct.interestRecalculationData.recalculationCompoundingFrequencyNthDay?.value }}</span>
|
||||
<span
|
||||
*ngIf="(loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && !loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay) || loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 3"> {{
|
||||
loanProduct.interestRecalculationData.recalculationCompoundingFrequencyWeekday?.value }}</span>
|
||||
<span
|
||||
*ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay"> {{
|
||||
'on day ' + loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay }}</span>
|
||||
</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id !== 1"
|
||||
fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency Interval for compounding:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationCompoundingFrequencyInterval }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency for recalculate Outstanding Principal:</span>
|
||||
<span fxFlex="60%">
|
||||
{{ loanProduct.interestRecalculationData.recalculationRestFrequencyType.value }}
|
||||
<span
|
||||
*ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationRestFrequencyNthDay"> {{
|
||||
'on ' + loanProduct.interestRecalculationData.recalculationRestFrequencyNthDay?.value }}</span>
|
||||
<span
|
||||
*ngIf="(loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && !loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay) || loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 3"> {{
|
||||
loanProduct.interestRecalculationData.recalculationRestFrequencyWeekday?.value }}</span>
|
||||
<span
|
||||
*ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay"> {{
|
||||
'on day ' + loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id !== 1"
|
||||
fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency Interval for recalculation:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationRestFrequencyInterval }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.recalculationRestFrequencyDate">
|
||||
<span fxFlex="40%">Rest Frequency Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationRestFrequencyDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Arrears recognization based on original schedule:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isArrearsBasedOnOriginalSchedule ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Guarantee Requirements</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Place Guarantee Funds On-Hold:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.holdGuaranteeFunds ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.holdGuaranteeFunds" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Mandatory Guarantee(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.mandatoryGuarantee }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.productGuaranteeData.minimumGuaranteeFromOwnFunds">
|
||||
<span fxFlex="40%">Minimum Guarantee from Own Funds(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.minimumGuaranteeFromOwnFunds }}</span>
|
||||
</div>
|
||||
<div fxFlexFill *ngIf="loanProduct.productGuaranteeData.minimumGuaranteeFromGuarantor">
|
||||
<span fxFlex="40%">Minimum Guarantee from Guarantor Funds(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.minimumGuaranteeFromGuarantor }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Loan Tranche Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enable Multiple Disbursals:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.multiDisburseLoan ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.multiDisburseLoan" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Maximum Tranche count:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.maxTrancheCount }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.outstandingLoanBalance">
|
||||
<span fxFlex="40%">Maximum allowed outstanding balance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.outstandingLoanBalance }}</span>
|
||||
</div>
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Disallow Expected Disbursements:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.disallowExpectedDisbursements ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Configurable Terms and Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow overriding select terms and settings in loan accounts:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeConfiguration ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowAttributeConfiguration" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.amortizationType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Interest method:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.interestType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Repayment strategy:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.transactionProcessingStrategyCode ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Interest calculation period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.interestCalculationPeriodType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Arrears tolerance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.inArrearsTolerance ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Repaid every:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.repaymentEvery ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Moratorium:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.graceOnPrincipalAndInterestPayment ? 'Yes' : 'No'
|
||||
}}</span>
|
||||
<span fxFlex="40%">Number of days a loan may be overdue before moving into arrears:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.graceOnArrearsAgeing ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Delinquency Bucket:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.delinquencyBucket.id ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table
|
||||
[dataSource]="loanProduct.charges | chargesPenaltyFilter:false">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Overdue Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.charges | chargesPenaltyFilter:true">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.name + ', ' + overdueCharge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Accounting</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Type:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.accountingRule.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.accountingRule.id >= 2 && loanProduct.accountingRule.id <= 4" fxLayout="row wrap"
|
||||
fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets / Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Fund source:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.fundSourceAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.fundSourceAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Loan portfolio:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.loanPortfolioAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.loanPortfolioAccount.name }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.accountingRule.id === 3 || loanProduct.accountingRule.id === 4"
|
||||
fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Interest Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivableInterestAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.receivableInterestAccount.name }}</span>
|
||||
<span fxFlex="40%">Fees Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivableInterestAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.receivableInterestAccount.name }}</span>
|
||||
<span fxFlex="40%">Penalties Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivablePenaltyAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.receivablePenaltyAccount.name }}</span>
|
||||
</div>
|
||||
<span fxFlex="40%">Transfer in suspense:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.transfersInSuspenseAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.transfersInSuspenseAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Income</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Income from Interest:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.interestOnLoanAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.interestOnLoanAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from fees:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromFeeAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.incomeFromFeeAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from penalties:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromPenaltyAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.incomeFromPenaltyAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from Recovery Repayments:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromRecoveryAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.incomeFromRecoveryAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Losses written off:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.writeOffAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.writeOffAccount.name }}</span>
|
||||
<span fxFlex="40%">Goodwill credit:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.goodwillCreditAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.goodwillCreditAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Over payment liability:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.overpaymentLiabilityAccount.glCode}}) {{
|
||||
loanProduct.accountingMappings.overpaymentLiabilityAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="loanProduct.paymentChannelToFundSourceMappings?.length || loanProduct.feeToIncomeAccountMappings?.length || loanProduct.penaltyToIncomeAccountMappings?.length"
|
||||
fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div *ngIf="loanProduct.paymentChannelToFundSourceMappings?.length" fxFlexFill fxLayout="row wrap"
|
||||
fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fund Sources for Payment Channels</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table
|
||||
[dataSource]="loanProduct.paymentChannelToFundSourceMappings">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentType.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanProduct.feeToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap"
|
||||
fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fees to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.feeToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap"
|
||||
fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Penalties to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.penaltyToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
@import "assets/styles/helper";
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
}
|
||||
|
||||
.mat-h3 {
|
||||
margin-top: 10px !important;
|
||||
font-weight: 300;
|
||||
color: $status-approved;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GeneralTabComponent } from './general-tab.component';
|
||||
|
||||
describe('GeneralTabComponent', () => {
|
||||
let component: GeneralTabComponent;
|
||||
let fixture: ComponentFixture<GeneralTabComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GeneralTabComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GeneralTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-general-tab',
|
||||
templateUrl: './general-tab.component.html',
|
||||
styleUrls: ['./general-tab.component.scss']
|
||||
})
|
||||
export class GeneralTabComponent implements OnInit {
|
||||
|
||||
loanProduct: any;
|
||||
|
||||
variationsDisplayedColumns: string[] = ['valueConditionType', 'borrowerCycleNumber', 'minValue', 'defaultValue', 'maxValue'];
|
||||
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId'];
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { loanProduct: any }) => {
|
||||
this.loanProduct = data.loanProduct;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loanProduct.allowAttributeConfiguration = Object.values(this.loanProduct.allowAttributeOverrides).some((attribute: boolean) => attribute);
|
||||
}
|
||||
|
||||
}
|
||||
+18
-751
@@ -1,756 +1,23 @@
|
||||
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_LOANPRODUCT'">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="product-card">
|
||||
|
||||
<div class="container">
|
||||
<mat-card-content>
|
||||
|
||||
<mat-card>
|
||||
<nav mat-tab-nav-bar class="navigation-tabs">
|
||||
<a mat-tab-link [routerLink]="['./general']" routerLinkActive #general="routerLinkActive"
|
||||
[active]="general.isActive">
|
||||
General
|
||||
</a>
|
||||
<ng-container *ngFor="let loanProductDatatable of loanProductDatatables">
|
||||
<a mat-tab-link [routerLink]="['./datatables',loanProductDatatable.registeredTableName]" routerLinkActive
|
||||
#datatable="routerLinkActive" [active]="datatable.isActive"
|
||||
*mifosxHasPermission="'READ_' + loanProductDatatable.registeredTableName">
|
||||
{{loanProductDatatable.registeredTableName}}
|
||||
</a>
|
||||
</ng-container>
|
||||
</nav>
|
||||
|
||||
<mat-card-content>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
</mat-card-content>
|
||||
|
||||
<h2 class="mat-h2" fxFlexFill>{{ loanProduct.name }}</h2>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Short Name:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.shortName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.fundId">
|
||||
<span fxFlex="40%">Fund Name:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.fundName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Include in Customer Loan Counter:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.includeInBorrowerCycle ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.startDate">
|
||||
<span fxFlex="40%">Start Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.startDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.closeDate">
|
||||
<span fxFlex="40%">Close Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.closeDate | dateFormat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.description }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Decimal Places:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.decimalPlaces }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency in multiples of:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.currency.inMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Installment in multiples of:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.installmentAmountInMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Principal:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.principal + ' (Min: ' + (loanProduct.minPrincipal ? loanProduct.minPrincipal : loanProduct.principal) + ', Max: ' + (loanProduct.maxPrincipal ? loanProduct.maxPrincipal : loanProduct.principal) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow Approved / Disbursed Amounts Over Applied:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowApprovedDisbursedAmountsOverApplied ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowApprovedDisbursedAmountsOverApplied">
|
||||
<span fxFlex="40%">Over Applied Amount:</span>
|
||||
<span fxFlex="60%" *ngIf="loanProduct.overAppliedCalculationType === 'percentage'">{{ loanProduct.overAppliedNumber }} %</span>
|
||||
<span fxFlex="60%" *ngIf="loanProduct.overAppliedCalculationType === 'flat'">{{ loanProduct.overAppliedNumber }} {{ loanProduct.currencyCode }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Number of Repayments:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.numberOfRepayments + ' (Min: ' + (loanProduct.minNumberOfRepayments ? loanProduct.minNumberOfRepayments : loanProduct.numberOfRepayments) + ', Max: ' + (loanProduct.maxNumberOfRepayments ? loanProduct.maxNumberOfRepayments : loanProduct.numberOfRepayments) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Linked to floating interest rates:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isLinkedToFloatingInterestRates ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="!loanProduct.isLinkedToFloatingInterestRates">
|
||||
<span fxFlex="40%">Nominal interest rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRatePerPeriod + ' (Min: ' + (loanProduct.minInterestRatePerPeriod ? loanProduct.minInterestRatePerPeriod : loanProduct.interestRatePerPeriod) + ', Max: ' + (loanProduct.maxInterestRatePerPeriod ? loanProduct.maxInterestRatePerPeriod : loanProduct.interestRatePerPeriod) + ')' + ' ' + loanProduct.interestRateFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.isLinkedToFloatingInterestRates" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Floating Lending Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.floatingRateName }}</span>
|
||||
<span fxFlex="40%">Interest Rate Differential:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRateDifferential }}</span>
|
||||
<span fxFlex="40%">Floating Interest Rate Calculation Allowed:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isFloatingInterestRateCalculationAllowed ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Floating Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.defaultDifferentialLendingRate + ' (Min: ' + (loanProduct.minDifferentialLendingRate ? loanProduct.minDifferentialLendingRate : loanProduct.defaultDifferentialLendingRate) + ', Max: ' + (loanProduct.maxDifferentialLendingRate ? loanProduct.maxDifferentialLendingRate : loanProduct.defaultDifferentialLendingRate) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Terms vary based on loan cycle:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.useBorrowerCycle ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.principalVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Principal by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.principalVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.numberOfRepaymentVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Number of Repayments by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.numberOfRepaymentVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRateVariationsForBorrowerCycle?.length">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Nominal Interest Rate by loan cycle</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.interestRateVariationsForBorrowerCycle">
|
||||
|
||||
<ng-container matColumnDef="valueConditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.valueConditionType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="borrowerCycleNumber">
|
||||
<th mat-header-cell *matHeaderCellDef> Loan Cycle </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.borrowerCycleNumber }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="minValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Minimum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.minValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="defaultValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Default </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.defaultValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Maximum </th>
|
||||
<td mat-cell *matCellDef="let variation">
|
||||
{{ variation.maxValue }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="variationsDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: variationsDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Repay Every:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.repaymentEvery + ' ' + loanProduct.repaymentFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.minimumDaysBetweenDisbursalAndFirstRepayment">
|
||||
<span fxFlex="40%">Minimum days between disbursal and first repayment date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.minimumDaysBetweenDisbursalAndFirstRepayment }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.amortizationType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Equal Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isEqualAmortization ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Method:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Calculation Period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestCalculationPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.interestCalculationPeriodType.id === 1">
|
||||
<span fxFlex="40%">Allow Partial Interest Calculation with same as repayment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowPartialPeriodInterestCalcualtion ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Repayment Strategy:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.transactionProcessingStrategyName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnPrincipalPayment">
|
||||
<span fxFlex="40%">Grace on principal payment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnPrincipalPayment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnInterestPayment">
|
||||
<span fxFlex="40%">Grace on interest payment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnInterestPayment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnInterestCharged">
|
||||
<span fxFlex="40%">Interest free period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnInterestCharged }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.inArrearsTolerance">
|
||||
<span fxFlex="40%">Arrears tolerance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.inArrearsTolerance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in year:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.daysInYearType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in month:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.daysInMonthType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow fixing of the installment amount:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.canDefineInstallmentAmount ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.graceOnArrearsAgeing">
|
||||
<span fxFlex="40%">Number of days a loan may be overdue before moving into arrears:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.graceOnArrearsAgeing }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.overdueDaysForNPA">
|
||||
<span fxFlex="40%">Maximum number of days a loan may be overdue before becoming a NPA (non performing asset):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.overdueDaysForNPA }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Account moves out of NPA only after all arrears have been cleared:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.accountMovesOutOfNPAOnlyOnArrearsCompletion ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.principalThresholdForLastInstallment">
|
||||
<span fxFlex="40%">Principal Threshold (%) for Last Instalment:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.principalThresholdForLastInstallment }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Variable Installments allowed:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowVariableInstallments ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowVariableInstallments">
|
||||
<span fxFlex="40%">Variable Installments:</span>
|
||||
<span fxFlex="60%">{{ '(Min: ' + loanProduct.minimumGap + ', Max: ' + (loanProduct.maximumGap ? loanProduct.maximumGap : loanProduct.minimumGap) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allowed to be used for providing Topup Loans:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.canUseForTopup ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Interest Recalculation</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Recalculate Interest:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isInterestRecalculationEnabled ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.isInterestRecalculationEnabled" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Pre-closure interest calculation rule:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.preClosureInterestCalculationStrategy.value }}</span>
|
||||
<span fxFlex="40%">Advance payments adjustment type:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.rescheduleStrategyType.value }}</span>
|
||||
<span fxFlex="40%">Interest recalculation compounding on:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.interestRecalculationCompoundingType.value }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.interestRecalculationCompoundingType.id !== 0" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency for compounding:</span>
|
||||
<span fxFlex="60%">
|
||||
{{ loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.value }}
|
||||
<span *ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationCompoundingFrequencyNthDay"> {{ 'on ' + loanProduct.interestRecalculationData.recalculationCompoundingFrequencyNthDay?.value }}</span>
|
||||
<span *ngIf="(loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && !loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay) || loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 3"> {{ loanProduct.interestRecalculationData.recalculationCompoundingFrequencyWeekday?.value }}</span>
|
||||
<span *ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay"> {{ 'on day ' + loanProduct.interestRecalculationData.recalculationCompoundingFrequencyOnDay }}</span>
|
||||
</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.recalculationCompoundingFrequencyType.id !== 1" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency Interval for compounding:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationCompoundingFrequencyInterval }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency for recalculate Outstanding Principal:</span>
|
||||
<span fxFlex="60%">
|
||||
{{ loanProduct.interestRecalculationData.recalculationRestFrequencyType.value }}
|
||||
<span *ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationRestFrequencyNthDay"> {{ 'on ' + loanProduct.interestRecalculationData.recalculationRestFrequencyNthDay?.value }}</span>
|
||||
<span *ngIf="(loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && !loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay) || loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 3"> {{ loanProduct.interestRecalculationData.recalculationRestFrequencyWeekday?.value }}</span>
|
||||
<span *ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id === 4 && loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay"> {{ 'on day ' + loanProduct.interestRecalculationData.recalculationRestFrequencyOnDay }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div fxFlexFill *ngIf="loanProduct.interestRecalculationData.recalculationRestFrequencyType.id !== 1" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Frequency Interval for recalculation:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationRestFrequencyInterval }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.recalculationRestFrequencyDate">
|
||||
<span fxFlex="40%">Rest Frequency Date:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.interestRecalculationData.recalculationRestFrequencyDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Arrears recognization based on original schedule:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.isArrearsBasedOnOriginalSchedule ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Guarantee Requirements</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Place Guarantee Funds On-Hold:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.holdGuaranteeFunds ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.holdGuaranteeFunds" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Mandatory Guarantee(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.mandatoryGuarantee }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.productGuaranteeData.minimumGuaranteeFromOwnFunds">
|
||||
<span fxFlex="40%">Minimum Guarantee from Own Funds(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.minimumGuaranteeFromOwnFunds }}</span>
|
||||
</div>
|
||||
<div fxFlexFill *ngIf="loanProduct.productGuaranteeData.minimumGuaranteeFromGuarantor">
|
||||
<span fxFlex="40%">Minimum Guarantee from Guarantor Funds(%):</span>
|
||||
<span fxFlex="60%">{{ loanProduct.productGuaranteeData.minimumGuaranteeFromGuarantor }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Loan Tranche Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enable Multiple Disbursals:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.multiDisburseLoan ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.multiDisburseLoan" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Maximum Tranche count:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.maxTrancheCount }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.outstandingLoanBalance">
|
||||
<span fxFlex="40%">Maximum allowed outstanding balance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.outstandingLoanBalance }}</span>
|
||||
</div>
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Disallow Expected Disbursements:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.disallowExpectedDisbursements ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Configurable Terms and Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Allow overriding select terms and settings in loan accounts:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeConfiguration ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.allowAttributeConfiguration" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Amortization:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.amortizationType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Interest method:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.interestType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Repayment strategy:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.transactionProcessingStrategyCode ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Interest calculation period:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.interestCalculationPeriodType ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Arrears tolerance:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.inArrearsTolerance ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Repaid every:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.repaymentEvery ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Moratorium:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.graceOnPrincipalAndInterestPayment ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Number of days a loan may be overdue before moving into arrears:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.allowAttributeOverrides.graceOnArrearsAgeing ? 'Yes' : 'No' }}</span>
|
||||
<span fxFlex="40%">Delinquency Bucket:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.delinquencyBucket.id ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.charges | chargesPenaltyFilter:false">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Overdue Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.charges | chargesPenaltyFilter:true">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.name + ', ' + overdueCharge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let overdueCharge">
|
||||
{{ overdueCharge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Accounting</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Type:</span>
|
||||
<span fxFlex="60%">{{ loanProduct.accountingRule.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="loanProduct.accountingRule.id >= 2 && loanProduct.accountingRule.id <= 4" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets / Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Fund source:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.fundSourceAccount.glCode}}) {{ loanProduct.accountingMappings.fundSourceAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Loan portfolio:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.loanPortfolioAccount.glCode}}) {{ loanProduct.accountingMappings.loanPortfolioAccount.name }}</span>
|
||||
<div fxFlexFill *ngIf="loanProduct.accountingRule.id === 3 || loanProduct.accountingRule.id === 4" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Interest Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivableInterestAccount.glCode}}) {{ loanProduct.accountingMappings.receivableInterestAccount.name }}</span>
|
||||
<span fxFlex="40%">Fees Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivableInterestAccount.glCode}}) {{ loanProduct.accountingMappings.receivableInterestAccount.name }}</span>
|
||||
<span fxFlex="40%">Penalties Receivable:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.receivablePenaltyAccount.glCode}}) {{ loanProduct.accountingMappings.receivablePenaltyAccount.name }}</span>
|
||||
</div>
|
||||
<span fxFlex="40%">Transfer in suspense:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.transfersInSuspenseAccount.glCode}}) {{ loanProduct.accountingMappings.transfersInSuspenseAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Income</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Income from Interest:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.interestOnLoanAccount.glCode}}) {{ loanProduct.accountingMappings.interestOnLoanAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from fees:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromFeeAccount.glCode}}) {{ loanProduct.accountingMappings.incomeFromFeeAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from penalties:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromPenaltyAccount.glCode}}) {{ loanProduct.accountingMappings.incomeFromPenaltyAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from Recovery Repayments:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.incomeFromRecoveryAccount.glCode}}) {{ loanProduct.accountingMappings.incomeFromRecoveryAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Losses written off:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.writeOffAccount.glCode}}) {{ loanProduct.accountingMappings.writeOffAccount.name }}</span>
|
||||
<span fxFlex="40%">Goodwill credit:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.goodwillCreditAccount.glCode}}) {{ loanProduct.accountingMappings.goodwillCreditAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Over payment liability:</span>
|
||||
<span fxFlex="60%">({{loanProduct.accountingMappings.overpaymentLiabilityAccount.glCode}}) {{ loanProduct.accountingMappings.overpaymentLiabilityAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanProduct.paymentChannelToFundSourceMappings?.length || loanProduct.feeToIncomeAccountMappings?.length || loanProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div *ngIf="loanProduct.paymentChannelToFundSourceMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fund Sources for Payment Channels</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.paymentChannelToFundSourceMappings">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentType.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanProduct.feeToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fees to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.feeToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="loanProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Penalties to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="loanProduct.penaltyToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
.product-card {
|
||||
margin: 0 auto;
|
||||
max-width: 80rem;
|
||||
width: 90%;
|
||||
padding: 0;
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
h2, h3, h4 {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
.mat-card .mat-divider-horizontal.mat-divider-inset {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
.navigation-tabs {
|
||||
overflow: auto;
|
||||
}
|
||||
i:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,21 +8,15 @@ import { ActivatedRoute } from '@angular/router';
|
||||
})
|
||||
export class ViewLoanProductComponent implements OnInit {
|
||||
|
||||
loanProduct: any;
|
||||
|
||||
variationsDisplayedColumns: string[] = ['valueConditionType', 'borrowerCycleNumber', 'minValue', 'defaultValue', 'maxValue'];
|
||||
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId'];
|
||||
loanProductDatatables: any = [];
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { loanProduct: any }) => {
|
||||
this.loanProduct = data.loanProduct;
|
||||
this.route.data.subscribe((data: { loanProductDatatables: any }) => {
|
||||
this.loanProductDatatables = data.loanProductDatatables;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loanProduct.allowAttributeConfiguration = Object.values(this.loanProduct.allowAttributeOverrides).some((attribute: boolean) => attribute);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -112,6 +112,14 @@ import { CreateRangeComponent } from './manage-delinquency-buckets/delinquency-r
|
||||
import { CreateBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component';
|
||||
import { EditBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component';
|
||||
import { ViewBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component';
|
||||
import { LoanProductDatatablesResolver } from './loan-products/loan-product-datatables.resolver';
|
||||
import { GeneralTabComponent } from './loan-products/view-loan-product/general-tab/general-tab.component';
|
||||
import { DatatableTabComponent } from './loan-products/view-loan-product/datatable-tab/datatable-tab.component';
|
||||
import { LoanProductDatatableResolver } from './loan-products/loan-product-datatable.resolver';
|
||||
import { SavingProductDatatableResolver } from './saving-products/saving-product-datatable.resolver';
|
||||
import { SavingProductDatatablesResolver } from './saving-products/saving-product-datatables.resolver';
|
||||
import { SavingProductGeneralTabComponent } from './saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component';
|
||||
import { SavingProductDatatableTabComponent } from './saving-products/view-saving-product/saving-product-datatable-tab/saving-product-datatable-tab.component';
|
||||
|
||||
/** Products Routes */
|
||||
const routes: Routes = [
|
||||
@@ -140,22 +148,41 @@ const routes: Routes = [
|
||||
component: CreateLoanProductComponent,
|
||||
data: { title: extract('Create Loan Product'), breadcrumb: 'Create' },
|
||||
resolve: {
|
||||
loanProductsTemplate: LoanProductsTemplateResolver
|
||||
loanProductsTemplate: LoanProductsTemplateResolver,
|
||||
loanProductDatatables: LoanProductDatatablesResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
data: { title: extract('View Loan Product'), routeParamBreadcrumb: 'id' },
|
||||
path: ':productId',
|
||||
component: ViewLoanProductComponent,
|
||||
resolve: {
|
||||
loanProduct: LoanProductResolver
|
||||
loanProductDatatables: LoanProductDatatablesResolver
|
||||
},
|
||||
data: { title: extract('View Loan Product'), breadcrumb: 'productId', routeParamBreadcrumb: 'productId' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ViewLoanProductComponent,
|
||||
redirectTo: 'general',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'general',
|
||||
data: { title: extract('General'), breadcrumb: 'General', routeParamBreadcrumb: false },
|
||||
component: GeneralTabComponent,
|
||||
resolve: {
|
||||
loanProduct: LoanProductResolver
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'datatables',
|
||||
children: [{
|
||||
path: ':datatableName',
|
||||
component: DatatableTabComponent,
|
||||
data: { title: extract('Data Table View'), routeParamBreadcrumb: 'datatableName' },
|
||||
resolve: {
|
||||
loanProductDatatable: LoanProductDatatableResolver
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: 'edit',
|
||||
@@ -185,22 +212,40 @@ const routes: Routes = [
|
||||
component: CreateSavingProductComponent,
|
||||
data: { title: extract('Create Saving Product'), breadcrumb: 'Create' },
|
||||
resolve: {
|
||||
savingProductsTemplate: SavingProductsTemplateResolver
|
||||
savingProductDatatables: SavingProductDatatablesResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
data: { title: extract('View Saving Product'), routeParamBreadcrumb: 'id' },
|
||||
path: ':productId',
|
||||
component: ViewSavingProductComponent,
|
||||
data: { title: extract('View Saving Product'), breadcrumb: 'productId', routeParamBreadcrumb: 'productId' },
|
||||
resolve: {
|
||||
savingProduct: SavingProductResolver
|
||||
savingProductDatatables: SavingProductDatatablesResolver
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ViewSavingProductComponent,
|
||||
redirectTo: 'general',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'general',
|
||||
data: { title: extract('General'), breadcrumb: 'General', routeParamBreadcrumb: false },
|
||||
component: SavingProductGeneralTabComponent,
|
||||
resolve: {
|
||||
savingProduct: SavingProductResolver
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'datatables',
|
||||
children: [{
|
||||
path: ':datatableName',
|
||||
component: SavingProductDatatableTabComponent,
|
||||
data: { title: extract('Data Table View'), routeParamBreadcrumb: 'datatableName' },
|
||||
resolve: {
|
||||
savingProductDatatable: SavingProductDatatableResolver
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: 'edit',
|
||||
|
||||
@@ -106,6 +106,11 @@ import { EditRangeComponent } from './manage-delinquency-buckets/delinquency-ran
|
||||
import { ViewBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/view-bucket/view-bucket.component';
|
||||
import { CreateBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/create-bucket/create-bucket.component';
|
||||
import { EditBucketComponent } from './manage-delinquency-buckets/delinquency-bucket/edit-bucket/edit-bucket.component';
|
||||
import { LoanProductDatatableStepComponent } from './loan-products/loan-product-stepper/loan-product-datatable-step/loan-product-datatable-step.component';
|
||||
import { DatatableTabComponent } from './loan-products/view-loan-product/datatable-tab/datatable-tab.component';
|
||||
import { GeneralTabComponent } from './loan-products/view-loan-product/general-tab/general-tab.component';
|
||||
import { SavingProductGeneralTabComponent } from './saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component';
|
||||
import { SavingProductDatatableTabComponent } from './saving-products/view-saving-product/saving-product-datatable-tab/saving-product-datatable-tab.component';
|
||||
|
||||
/**
|
||||
* Products Module
|
||||
@@ -219,7 +224,12 @@ import { EditBucketComponent } from './manage-delinquency-buckets/delinquency-bu
|
||||
EditRangeComponent,
|
||||
ViewBucketComponent,
|
||||
CreateBucketComponent,
|
||||
EditBucketComponent
|
||||
EditBucketComponent,
|
||||
LoanProductDatatableStepComponent,
|
||||
DatatableTabComponent,
|
||||
GeneralTabComponent,
|
||||
SavingProductGeneralTabComponent,
|
||||
SavingProductDatatableTabComponent
|
||||
],
|
||||
entryComponents: [
|
||||
DepositProductIncentiveFormDialogComponent,
|
||||
|
||||
@@ -542,4 +542,54 @@ export class ProductsService {
|
||||
return this.http.post('/collateral-management', collateral);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} product Product type.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getProductDatatables(product: string): Observable<any> {
|
||||
const httpParams = new HttpParams().set('apptable', product);
|
||||
return this.http.get(`/datatables`, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} productId Product Id.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getProductDatatable(productId: string, datatableName: string) {
|
||||
const httpParams = new HttpParams().set('genericResultSet', 'true');
|
||||
return this.http.get(`/datatables/${datatableName}/${productId}`, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} productId Product Id.
|
||||
* @param {string} datatableName Datatable name
|
||||
* @param {any} data Payload.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
addProductDatatableEntry(productId: string, datatableName: string, data: any) {
|
||||
const httpParams = new HttpParams().set('genericResultSet', 'true');
|
||||
return this.http.post(`/datatables/${datatableName}/${productId}`, data, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} productId Product Id.
|
||||
* @param {string} datatableName Datatable name
|
||||
* @param {any} data Payload.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
editProductDatatableEntry(productId: string, datatableName: string, data: any) {
|
||||
const httpParams = new HttpParams().set('genericResultSet', 'true');
|
||||
return this.http.put(`/datatables/${datatableName}/${productId}`, data, { params: httpParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} productId Product Id.
|
||||
* @param {string} datatableName Datatable name
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
deleteDatatableContent(productId: string, datatableName: string) {
|
||||
const httpParams = new HttpParams().set('genericResultSet', 'true');
|
||||
return this.http.delete(`/datatables/${datatableName}/${productId}`, { params: httpParams });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@ export class SavingProductAndTemplateResolver implements Resolve<Object> {
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const savingProductId = route.paramMap.get('id');
|
||||
return this.productsService.getSavingProduct(savingProductId, true);
|
||||
const productId = route.paramMap.get('productId');
|
||||
return this.productsService.getSavingProduct(productId, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SavingProductDatatableResolver } from './saving-product-datatable.resolver';
|
||||
|
||||
describe('SavingProductDatatableResolver', () => {
|
||||
let resolver: SavingProductDatatableResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
resolver = TestBed.inject(SavingProductDatatableResolver);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(resolver).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SavingProductDatatableResolver implements Resolve<boolean> {
|
||||
|
||||
/**
|
||||
* @param {SystemService} systemService Products service.
|
||||
*/
|
||||
constructor(private systemService: SystemService) { }
|
||||
|
||||
/**
|
||||
* Returns the loan product data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const productId = route.parent.parent.paramMap.get('productId');
|
||||
const datatableName = route.paramMap.get('datatableName');
|
||||
return this.systemService.getEntityDatatable(productId, datatableName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SavingProductDatatablesResolver } from './saving-product-datatables.resolver';
|
||||
|
||||
describe('SavingProductDatatablesResolver', () => {
|
||||
let resolver: SavingProductDatatablesResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
resolver = TestBed.inject(SavingProductDatatablesResolver);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(resolver).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
Router, Resolve,
|
||||
RouterStateSnapshot,
|
||||
ActivatedRouteSnapshot
|
||||
} from '@angular/router';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { Observable, of } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SavingProductDatatablesResolver implements Resolve<boolean> {
|
||||
|
||||
/**
|
||||
* @param {SystemService} systemService Products service.
|
||||
*/
|
||||
constructor(private systemService: SystemService) { }
|
||||
|
||||
/**
|
||||
* Returns the loan product data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
return this.systemService.getEntityDatatables('m_savings_product');
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@ export class SavingProductResolver implements Resolve<Object> {
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const id = route.paramMap.get('id');
|
||||
return this.productsService.getSavingProduct(id);
|
||||
const productId = route.parent.paramMap.get('productId');
|
||||
return this.productsService.getSavingProduct(productId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<div class="tab-container mat-typography">
|
||||
<mifosx-entity-datatable-tab
|
||||
entityType="Savings Product"
|
||||
[entityId]="entityId"
|
||||
[multiRowDatatableFlag]="multiRowDatatableFlag"
|
||||
[entityDatatable]="entityDatatable"
|
||||
>
|
||||
</mifosx-entity-datatable-tab>
|
||||
</div>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SavingProductDatatableTabComponent } from './saving-product-datatable-tab.component';
|
||||
|
||||
describe('SavingProductDatatableTabComponent', () => {
|
||||
let component: SavingProductDatatableTabComponent;
|
||||
let fixture: ComponentFixture<SavingProductDatatableTabComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SavingProductDatatableTabComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SavingProductDatatableTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-saving-product-datatable-tab',
|
||||
templateUrl: './saving-product-datatable-tab.component.html',
|
||||
styleUrls: ['./saving-product-datatable-tab.component.scss']
|
||||
})
|
||||
export class SavingProductDatatableTabComponent implements OnInit {
|
||||
entityId: string;
|
||||
entityDatatable: any;
|
||||
multiRowDatatableFlag: boolean;
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.entityId = this.route.parent.parent.snapshot.paramMap.get('productId');
|
||||
|
||||
this.route.data.subscribe((data: { savingProductDatatable: any }) => {
|
||||
this.entityDatatable = data.savingProductDatatable;
|
||||
this.multiRowDatatableFlag = this.entityDatatable.columnHeaders[0].columnName === 'id' ? true : false;
|
||||
});
|
||||
|
||||
}
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
+353
@@ -0,0 +1,353 @@
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_SAVINGSPRODUCT'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>Edit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<mat-card>
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h2 class="mat-h2" fxFlexFill>{{ savingProduct.name }}</h2>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Short Name:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.shortName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.description }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Decimal Places:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.decimalPlaces }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency in multiples of:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.inMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Nominal Annual Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.nominalAnnualInterestRate }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Compounding Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCompoundingPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Posting Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestPostingPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Calculated using:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCalculationType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in Year:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCalculationDaysInYearType.value }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minRequiredOpeningBalance">
|
||||
<span fxFlex="40%">Minimum Opening Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minRequiredOpeningBalance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.lockinPeriodFrequency">
|
||||
<span fxFlex="40%">Lock-in Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.lockinPeriodFrequency + ' ' + savingProduct.lockinPeriodFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Apply Withdrawal Fee for Transfers:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.withdrawalFeeForTransfers ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minBalanceForInterestCalculation">
|
||||
<span fxFlex="40%">Balance Required for Interest Calculation:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minBalanceForInterestCalculation }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enforce Minimum Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.enforceMinRequiredBalance ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minRequiredBalance">
|
||||
<span fxFlex="40%">Minimum Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minRequiredBalance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Withhold Tax is Applicable:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.withHoldTax ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.withHoldTax">
|
||||
<span fxFlex="40%">Tax Group:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.taxGroup.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Overdraft Allowed:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.allowOverdraft ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minOverdraftForInterestCalculation">
|
||||
<span fxFlex="40%">Minimum Overdraft Required for Interest Calculation:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minOverdraftForInterestCalculation }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.nominalAnnualInterestRateOverdraft">
|
||||
<span fxFlex="40%">Nominal Annual Interest for Overdraft:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.nominalAnnualInterestRateOverdraft }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.overdraftLimit">
|
||||
<span fxFlex="40%">Maximum Overdraft Amount Limit:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.overdraftLimit }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enable Dormancy Tracking:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.isDormancyTrackingActive ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.isDormancyTrackingActive" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Number of Days to Inactive sub-status:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToInactive }}</span>
|
||||
<span fxFlex="40%">Number of Days to Dormant sub-status:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToDormancy }}</span>
|
||||
<span fxFlex="40%">Number of Days to Escheat:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToEscheat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.charges">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Accounting</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Type:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingRule.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.accountingRule.id === 2" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Saving reference:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.savingsReferenceAccount.name }}</span>
|
||||
<span fxFlex="40%">Overdraft portfolio:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.overdraftPortfolioControl.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Saving control:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.savingsControlAccount.name }}</span>
|
||||
<span fxFlex="40%">Savings transfers in suspense:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.transfersInSuspenseAccount.name }}</span>
|
||||
<div fxFlexFill *ngIf="savingProduct.isDormancyTrackingActive">
|
||||
<span fxFlex="40%">Escheat liability:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.escheatLiabilityAccount.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Interest on savings:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.interestOnSavingsAccount.name }}</span>
|
||||
<span fxFlex="40%">Write-off:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.writeOffAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Income</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Income from fees:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromFeeAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from penalties:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromPenaltyAccount.name }}</span>
|
||||
<span fxFlex="40%">Overdraft Interest Income:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromInterest.name }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.paymentChannelToFundSourceMappings?.length || savingProduct.feeToIncomeAccountMappings?.length || savingProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div *ngIf="savingProduct.paymentChannelToFundSourceMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fund Sources for Payment Channels</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.paymentChannelToFundSourceMappings">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentType.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.feeToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fees to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.feeToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Penalties to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.penaltyToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
@import "assets/styles/helper";
|
||||
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
}
|
||||
|
||||
.mat-h3 {
|
||||
margin-top: 10px !important;
|
||||
font-weight: 300;
|
||||
color: $status-approved;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SavingProductGeneralTabComponent } from './saving-product-general-tab.component';
|
||||
|
||||
describe('SavingProductGeneralTabComponent', () => {
|
||||
let component: SavingProductGeneralTabComponent;
|
||||
let fixture: ComponentFixture<SavingProductGeneralTabComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SavingProductGeneralTabComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SavingProductGeneralTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-saving-product-general-tab',
|
||||
templateUrl: './saving-product-general-tab.component.html',
|
||||
styleUrls: ['./saving-product-general-tab.component.scss']
|
||||
})
|
||||
export class SavingProductGeneralTabComponent implements OnInit {
|
||||
savingProduct: any;
|
||||
|
||||
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId'];
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { savingProduct: any }) => {
|
||||
this.savingProduct = data.savingProduct;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
||||
+18
-348
@@ -1,353 +1,23 @@
|
||||
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_SAVINGSPRODUCT'">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
<mat-card class="product-card">
|
||||
|
||||
<div class="container">
|
||||
<mat-card-content>
|
||||
|
||||
<mat-card>
|
||||
<nav mat-tab-nav-bar class="navigation-tabs">
|
||||
<a mat-tab-link [routerLink]="['./general']" routerLinkActive #general="routerLinkActive"
|
||||
[active]="general.isActive">
|
||||
General
|
||||
</a>
|
||||
<ng-container *ngFor="let savingProductDatatable of savingProductDatatables">
|
||||
<a mat-tab-link [routerLink]="['./datatables',savingProductDatatable.registeredTableName]" routerLinkActive
|
||||
#datatable="routerLinkActive" [active]="datatable.isActive"
|
||||
*mifosxHasPermission="'READ_' + savingProductDatatable.registeredTableName">
|
||||
{{savingProductDatatable.registeredTableName}}
|
||||
</a>
|
||||
</ng-container>
|
||||
</nav>
|
||||
|
||||
<mat-card-content>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
</mat-card-content>
|
||||
|
||||
<h2 class="mat-h2" fxFlexFill>{{ savingProduct.name }}</h2>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Short Name:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.shortName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.description }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Decimal Places:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.decimalPlaces }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency in multiples of:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.currency.inMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Nominal Annual Interest Rate:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.nominalAnnualInterestRate }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Compounding Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCompoundingPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Posting Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestPostingPeriodType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Calculated using:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCalculationType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in Year:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.interestCalculationDaysInYearType.value }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minRequiredOpeningBalance">
|
||||
<span fxFlex="40%">Minimum Opening Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minRequiredOpeningBalance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.lockinPeriodFrequency">
|
||||
<span fxFlex="40%">Lock-in Period:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.lockinPeriodFrequency + ' ' + savingProduct.lockinPeriodFrequencyType.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Apply Withdrawal Fee for Transfers:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.withdrawalFeeForTransfers ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minBalanceForInterestCalculation">
|
||||
<span fxFlex="40%">Balance Required for Interest Calculation:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minBalanceForInterestCalculation }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enforce Minimum Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.enforceMinRequiredBalance ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minRequiredBalance">
|
||||
<span fxFlex="40%">Minimum Balance:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minRequiredBalance }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Withhold Tax is Applicable:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.withHoldTax ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.withHoldTax">
|
||||
<span fxFlex="40%">Tax Group:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.taxGroup.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Is Overdraft Allowed:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.allowOverdraft ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.minOverdraftForInterestCalculation">
|
||||
<span fxFlex="40%">Minimum Overdraft Required for Interest Calculation:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.minOverdraftForInterestCalculation }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.nominalAnnualInterestRateOverdraft">
|
||||
<span fxFlex="40%">Nominal Annual Interest for Overdraft:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.nominalAnnualInterestRateOverdraft }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.overdraftLimit">
|
||||
<span fxFlex="40%">Maximum Overdraft Amount Limit:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.overdraftLimit }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Enable Dormancy Tracking:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.isDormancyTrackingActive ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.isDormancyTrackingActive" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Number of Days to Inactive sub-status:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToInactive }}</span>
|
||||
<span fxFlex="40%">Number of Days to Dormant sub-status:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToDormancy }}</span>
|
||||
<span fxFlex="40%">Number of Days to Escheat:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.daysToEscheat }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.charges">
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Name </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.name + ', ' + charge.currency.displaySymbol }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeCalculationType">
|
||||
<th mat-header-cell *matHeaderCellDef> Type </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeCalculationType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="chargeTimeType">
|
||||
<th mat-header-cell *matHeaderCellDef> Collected On </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
{{ charge.chargeTimeType.value }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chargesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chargesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Accounting</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Type:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingRule.value }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="savingProduct.accountingRule.id === 2" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Saving reference:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.savingsReferenceAccount.name }}</span>
|
||||
<span fxFlex="40%">Overdraft portfolio:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.overdraftPortfolioControl.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Liabilities</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Saving control:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.savingsControlAccount.name }}</span>
|
||||
<span fxFlex="40%">Savings transfers in suspense:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.transfersInSuspenseAccount.name }}</span>
|
||||
<div fxFlexFill *ngIf="savingProduct.isDormancyTrackingActive">
|
||||
<span fxFlex="40%">Escheat liability:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.escheatLiabilityAccount.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Interest on savings:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.interestOnSavingsAccount.name }}</span>
|
||||
<span fxFlex="40%">Write-off:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.writeOffAccount.name }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Income</h4>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
<span fxFlex="40%">Income from fees:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromFeeAccount.name }}</span>
|
||||
<span fxFlex="40%">Income from penalties:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromPenaltyAccount.name }}</span>
|
||||
<span fxFlex="40%">Overdraft Interest Income:</span>
|
||||
<span fxFlex="60%">{{ savingProduct.accountingMappings.incomeFromInterest.name }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.paymentChannelToFundSourceMappings?.length || savingProduct.feeToIncomeAccountMappings?.length || savingProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-divider [inset]="true"></mat-divider>
|
||||
|
||||
<div *ngIf="savingProduct.paymentChannelToFundSourceMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fund Sources for Payment Channels</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.paymentChannelToFundSourceMappings">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentType.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.feeToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Fees to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.feeToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="savingProduct.penaltyToIncomeAccountMappings?.length" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 class="mat-h4" fxFlexFill>Penalties to Specific Income Accounts</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="savingProduct.penaltyToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.charge.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccount.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
</mat-card>
|
||||
|
||||
+11
-22
@@ -1,24 +1,13 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
.product-card {
|
||||
margin: 0 auto;
|
||||
max-width: 80rem;
|
||||
width: 90%;
|
||||
padding: 0;
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
h2, h3, h4 {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
.mat-card .mat-divider-horizontal.mat-divider-inset {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
.navigation-tabs {
|
||||
overflow: auto;
|
||||
}
|
||||
i:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-7
@@ -8,15 +8,11 @@ import { ActivatedRoute } from '@angular/router';
|
||||
})
|
||||
export class ViewSavingProductComponent implements OnInit {
|
||||
|
||||
savingProduct: any;
|
||||
|
||||
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId'];
|
||||
savingProductDatatables: any = [];
|
||||
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { savingProduct: any }) => {
|
||||
this.savingProduct = data.savingProduct;
|
||||
this.route.data.subscribe((data: { savingProductDatatables: any }) => {
|
||||
this.savingProductDatatables = data.savingProductDatatables;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user