feat: add create fixed deposit product component (#471)
- Add fixed deposit product stepper components - Add fixed deposit product component Fixes: #192
This commit is contained in:
@@ -6,7 +6,10 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
export class FindPipe implements PipeTransform {
|
||||
|
||||
transform(value: any, options: any, key: string, property: string): any {
|
||||
const optionFound = options.find((option: any) => option[key] === value);
|
||||
let optionFound;
|
||||
if (options) {
|
||||
optionFound = options.find((option: any) => option[key] === value);
|
||||
}
|
||||
return optionFound ? optionFound[property] : '';
|
||||
}
|
||||
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
<h1 mat-dialog-title>{{ title }}</h1>
|
||||
|
||||
<div mat-dialog-content [formGroup]="depositProductIncentiveForm" fxLayout="column">
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Attribute</mat-label>
|
||||
<mat-select formControlName="attributeName" required>
|
||||
<mat-option *ngFor="let attributeName of attributeNameData" [value]="attributeName.id">
|
||||
{{ attributeName.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Attribute is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Condition</mat-label>
|
||||
<mat-select formControlName="conditionType" required>
|
||||
<mat-option *ngFor="let conditionType of conditionTypeData" [value]="conditionType.id">
|
||||
{{ conditionType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Condition is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="depositProductIncentiveForm.value.attributeName">
|
||||
<mat-label>Value</mat-label>
|
||||
<mat-select formControlName="attributeValue" *ngIf="depositProductIncentiveForm.value.attributeName !== 3" required>
|
||||
<mat-option *ngFor="let attributeValue of attributeValueData" [value]="attributeValue.id">
|
||||
{{ attributeValue.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<input type="number" matInput formControlName="attributeValue" *ngIf="depositProductIncentiveForm.value.attributeName === 3" required>
|
||||
<mat-error>
|
||||
Value is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="incentiveType" required>
|
||||
<mat-option *ngFor="let incentiveType of incentiveTypeData" [value]="incentiveType.id">
|
||||
{{ incentiveType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Type is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Interest</mat-label>
|
||||
<input type="number" matInput formControlName="amount" required>
|
||||
<mat-error>
|
||||
Interest is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-dialog-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button mat-dialog-close> Cancel </button>
|
||||
<button mat-raised-button color="primary" [mat-dialog-close]="{ data: depositProductIncentiveForm }" [disabled]="!depositProductIncentiveForm.valid || depositProductIncentiveForm.pristine">{{ layout.addButtonText }}</button>
|
||||
</mat-dialog-actions>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DepositProductIncentiveFormDialogComponent } from './deposit-product-incentive-form-dialog.component';
|
||||
|
||||
describe('DepositProductIncentiveFormDialogComponent', () => {
|
||||
let component: DepositProductIncentiveFormDialogComponent;
|
||||
let fixture: ComponentFixture<DepositProductIncentiveFormDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DepositProductIncentiveFormDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DepositProductIncentiveFormDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-deposit-product-incentive-form-dialog',
|
||||
templateUrl: './deposit-product-incentive-form-dialog.component.html',
|
||||
styleUrls: ['./deposit-product-incentive-form-dialog.component.scss']
|
||||
})
|
||||
export class DepositProductIncentiveFormDialogComponent implements OnInit {
|
||||
|
||||
layout: {
|
||||
addButtonText?: string
|
||||
} = {
|
||||
addButtonText: 'Add'
|
||||
};
|
||||
|
||||
depositProductIncentiveForm: FormGroup;
|
||||
|
||||
title: string;
|
||||
|
||||
entityTypeData: any;
|
||||
attributeNameData: any;
|
||||
conditionTypeData: any;
|
||||
attributeValueData: any;
|
||||
incentiveTypeData: any;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<DepositProductIncentiveFormDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private formBuilder: FormBuilder) {
|
||||
this.createDepositProductIncentiveForm();
|
||||
this.setConditionalControls();
|
||||
this.layout = { ...this.layout, ...data.layout };
|
||||
this.dialogRef.disableClose = true;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.dialogRef.updateSize('400px');
|
||||
|
||||
this.entityTypeData = this.data.chartTemplate.entityTypeOptions;
|
||||
this.attributeNameData = this.data.chartTemplate.attributeNameOptions;
|
||||
this.conditionTypeData = this.data.chartTemplate.conditionTypeOptions;
|
||||
this.incentiveTypeData = this.data.chartTemplate.incentiveTypeOptions;
|
||||
|
||||
if (this.data.values) {
|
||||
this.depositProductIncentiveForm.patchValue({
|
||||
'entityType': this.data.values.entityType,
|
||||
'attributeName': this.data.values.attributeName,
|
||||
'conditionType': this.data.values.conditionType,
|
||||
'attributeValue': this.data.values.attributeValue,
|
||||
'incentiveType': this.data.values.incentiveType,
|
||||
'amount': this.data.values.amount
|
||||
});
|
||||
} else {
|
||||
this.depositProductIncentiveForm.patchValue({
|
||||
'entityType': this.data.entityType
|
||||
});
|
||||
}
|
||||
|
||||
this.title = `Incentives: ${this.entityTypeData.find((entityType: any) => this.depositProductIncentiveForm.get('entityType').value === entityType.id).value} Attributes`;
|
||||
}
|
||||
|
||||
setConditionalControls() {
|
||||
this.depositProductIncentiveForm.get('attributeName').valueChanges
|
||||
.subscribe((attributeName: any) => {
|
||||
this.depositProductIncentiveForm.patchValue({ 'attributeValue': '' });
|
||||
this.attributeValueData = this.data.chartTemplate[`${this.attributeNameData.find((option: any) => option.id === attributeName).code.split('.')[1]}Options`];
|
||||
});
|
||||
}
|
||||
|
||||
createDepositProductIncentiveForm() {
|
||||
this.depositProductIncentiveForm = this.formBuilder.group({
|
||||
'entityType': [''],
|
||||
'attributeName': ['', Validators.required],
|
||||
'conditionType': ['', Validators.required],
|
||||
'attributeValue': ['', Validators.required],
|
||||
'incentiveType': ['', Validators.required],
|
||||
'amount': ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
<div class="container">
|
||||
|
||||
<mat-horizontal-stepper class="mat-elevation-z8" labelPosition="bottom" #fixedDepositProductStepper>
|
||||
|
||||
<ng-template matStepperIcon="number">
|
||||
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||
</ng-template>
|
||||
|
||||
<ng-template matStepperIcon="edit">
|
||||
<fa-icon icon="pencil-alt" size="sm"></fa-icon>
|
||||
</ng-template>
|
||||
|
||||
<ng-template matStepperIcon="done">
|
||||
<fa-icon icon="check" size="sm"></fa-icon>
|
||||
</ng-template>
|
||||
|
||||
<ng-template matStepperIcon="error">
|
||||
<fa-icon icon="exclamation-triangle" size="lg"></fa-icon>
|
||||
</ng-template>
|
||||
|
||||
<ng-template matStepperIcon="preview">
|
||||
<fa-icon icon="eye" size="sm"></fa-icon>
|
||||
</ng-template>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductDetailsForm">
|
||||
|
||||
<ng-template matStepLabel>DETAILS</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-details-step></mifosx-fixed-deposit-product-details-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductCurrencyForm">
|
||||
|
||||
<ng-template matStepLabel>CURRENCY</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-currency-step [fixedDepositProductsTemplate]="fixedDepositProductsTemplate"></mifosx-fixed-deposit-product-currency-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductTermsForm">
|
||||
|
||||
<ng-template matStepLabel>TERMS</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-terms-step [fixedDepositProductsTemplate]="fixedDepositProductsTemplate"></mifosx-fixed-deposit-product-terms-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductSettingsForm">
|
||||
|
||||
<ng-template matStepLabel>SETTINGS</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-settings-step [fixedDepositProductsTemplate]="fixedDepositProductsTemplate"></mifosx-fixed-deposit-product-settings-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductInterestRateChartForm">
|
||||
|
||||
<ng-template matStepLabel>INTEREST RATE CHART</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-interest-rate-chart-step [fixedDepositProductsTemplate]="fixedDepositProductsTemplate"></mifosx-fixed-deposit-product-interest-rate-chart-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step>
|
||||
|
||||
<ng-template matStepLabel>CHARGES</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-charges-step
|
||||
[fixedDepositProductsTemplate]="fixedDepositProductsTemplate"
|
||||
[currencyCode]="fixedDepositProductCurrencyForm.get('currencyCode')"
|
||||
>
|
||||
</mifosx-fixed-deposit-product-charges-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step [stepControl]="fixedDepositProductAccountingForm">
|
||||
|
||||
<ng-template matStepLabel>ACCOUNTING</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-accounting-step
|
||||
[fixedDepositProductsTemplate]="fixedDepositProductsTemplate"
|
||||
[accountingRuleData]="accountingRuleData"
|
||||
[fixedDepositProductFormValid]="fixedDepositProductFormValid"
|
||||
>
|
||||
</mifosx-fixed-deposit-product-accounting-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
<mat-step state="preview" *ngIf="fixedDepositProductFormValid" completed>
|
||||
|
||||
<ng-template matStepLabel>PREVIEW</ng-template>
|
||||
|
||||
<mifosx-fixed-deposit-product-preview-step
|
||||
[fixedDepositProductsTemplate]="fixedDepositProductsTemplate"
|
||||
[chartSlabsDisplayedColumns]="fixedDepositProductInterestRateChartStep.chartSlabsDisplayedColumns"
|
||||
[accountingRuleData]="accountingRuleData"
|
||||
[fixedDepositProduct]="fixedDepositProduct"
|
||||
(submit)="submit()"
|
||||
>
|
||||
</mifosx-fixed-deposit-product-preview-step>
|
||||
|
||||
</mat-step>
|
||||
|
||||
</mat-horizontal-stepper>
|
||||
|
||||
</div>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CreateFixedDepositProductComponent } from './create-fixed-deposit-product.component';
|
||||
|
||||
describe('CreateFixedDepositProductComponent', () => {
|
||||
let component: CreateFixedDepositProductComponent;
|
||||
let fixture: ComponentFixture<CreateFixedDepositProductComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CreateFixedDepositProductComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CreateFixedDepositProductComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { FixedDepositProductDetailsStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component';
|
||||
import { FixedDepositProductCurrencyStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component';
|
||||
import { FixedDepositProductTermsStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component';
|
||||
import { FixedDepositProductSettingsStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component';
|
||||
import { FixedDepositProductInterestRateChartStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component';
|
||||
import { FixedDepositProductChargesStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component';
|
||||
import { FixedDepositProductAccountingStepComponent } from '../fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component';
|
||||
|
||||
import { ProductsService } from 'app/products/products.service';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-create-fixed-deposit-product',
|
||||
templateUrl: './create-fixed-deposit-product.component.html',
|
||||
styleUrls: ['./create-fixed-deposit-product.component.scss']
|
||||
})
|
||||
export class CreateFixedDepositProductComponent implements OnInit {
|
||||
|
||||
@ViewChild(FixedDepositProductDetailsStepComponent) fixedDepositProductDetailsStep: FixedDepositProductDetailsStepComponent;
|
||||
@ViewChild(FixedDepositProductCurrencyStepComponent) fixedDepositProductCurrencyStep: FixedDepositProductCurrencyStepComponent;
|
||||
@ViewChild(FixedDepositProductTermsStepComponent) fixedDepositProductTermsStep: FixedDepositProductTermsStepComponent;
|
||||
@ViewChild(FixedDepositProductSettingsStepComponent) fixedDepositProductSettingsStep: FixedDepositProductSettingsStepComponent;
|
||||
@ViewChild(FixedDepositProductInterestRateChartStepComponent) fixedDepositProductInterestRateChartStep: FixedDepositProductInterestRateChartStepComponent;
|
||||
@ViewChild(FixedDepositProductChargesStepComponent) fixedDepositProductChargesStep: FixedDepositProductChargesStepComponent;
|
||||
@ViewChild(FixedDepositProductAccountingStepComponent) fixedDepositProductAccountingStep: FixedDepositProductAccountingStepComponent;
|
||||
|
||||
fixedDepositProductsTemplate: any;
|
||||
accountingRuleData = ['None', 'Cash'];
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private productsService: ProductsService,
|
||||
private router: Router) {
|
||||
this.route.data.subscribe((data: { fixedDepositProductsTemplate: any }) => {
|
||||
this.fixedDepositProductsTemplate = data.fixedDepositProductsTemplate;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
get fixedDepositProductDetailsForm() {
|
||||
return this.fixedDepositProductDetailsStep.fixedDepositProductDetailsForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductCurrencyForm() {
|
||||
return this.fixedDepositProductCurrencyStep.fixedDepositProductCurrencyForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductTermsForm() {
|
||||
return this.fixedDepositProductTermsStep.fixedDepositProductTermsForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductSettingsForm() {
|
||||
return this.fixedDepositProductSettingsStep.fixedDepositProductSettingsForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductInterestRateChartForm() {
|
||||
return this.fixedDepositProductInterestRateChartStep.fixedDepositProductInterestRateChartForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductAccountingForm() {
|
||||
return this.fixedDepositProductAccountingStep.fixedDepositProductAccountingForm;
|
||||
}
|
||||
|
||||
get fixedDepositProductFormValid() {
|
||||
return (
|
||||
this.fixedDepositProductDetailsForm.valid &&
|
||||
this.fixedDepositProductCurrencyForm.valid &&
|
||||
this.fixedDepositProductTermsForm.valid &&
|
||||
this.fixedDepositProductSettingsForm.valid &&
|
||||
this.fixedDepositProductInterestRateChartForm.valid &&
|
||||
this.fixedDepositProductAccountingForm.valid
|
||||
);
|
||||
}
|
||||
|
||||
get fixedDepositProduct() {
|
||||
return {
|
||||
...this.fixedDepositProductDetailsStep.fixedDepositProductDetails,
|
||||
...this.fixedDepositProductCurrencyStep.fixedDepositProductCurrency,
|
||||
...this.fixedDepositProductTermsStep.fixedDepositProductTerms,
|
||||
...this.fixedDepositProductSettingsStep.fixedDepositProductSettings,
|
||||
...this.fixedDepositProductInterestRateChartStep.fixedDepositProductInterestRateChart,
|
||||
...this.fixedDepositProductChargesStep.fixedDepositProductCharges,
|
||||
...this.fixedDepositProductAccountingStep.fixedDepositProductAccounting
|
||||
};
|
||||
}
|
||||
|
||||
submit() {
|
||||
// TODO: Update once language and date settings are setup
|
||||
const fixedDepositProduct = {
|
||||
...this.fixedDepositProduct,
|
||||
charges: this.fixedDepositProduct.charges.map((charge: any) => ({ id: charge.id })),
|
||||
locale: 'en' // locale required for depositAmount
|
||||
};
|
||||
delete fixedDepositProduct.advancedAccountingRules;
|
||||
this.productsService.createFixedDepositProduct(fixedDepositProduct)
|
||||
.subscribe((response: any) => {
|
||||
this.router.navigate(['../', response.resourceId], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
<form [formGroup]="fixedDepositProductAccountingForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<mat-radio-group fxFlex="98%" fxLayout="row" fxLayoutGap="5%" fxLayout.lt-md="column" formControlName="accountingRule">
|
||||
<mat-radio-button *ngFor="let accountingRule of accountingRuleData; let i = index" [value]="i+1">
|
||||
{{ accountingRule }}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<div *ngIf="fixedDepositProductAccountingForm.value.accountingRule === 2" fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Assets</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Saving reference</mat-label>
|
||||
<mat-select formControlName="savingsReferenceAccountId" required>
|
||||
<mat-option *ngFor="let assetAccount of assetAccountData" [value]="assetAccount.id">
|
||||
{{ assetAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Saving reference is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Liabilities</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Saving control</mat-label>
|
||||
<mat-select formControlName="savingsControlAccountId" required>
|
||||
<mat-option *ngFor="let liabilityAccount of liabilityAccountData" [value]="liabilityAccount.id">
|
||||
{{ liabilityAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Saving control is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Savings transfers in suspense</mat-label>
|
||||
<mat-select formControlName="transfersInSuspenseAccountId" required>
|
||||
<mat-option *ngFor="let liabilityAccount of liabilityAccountData" [value]="liabilityAccount.id">
|
||||
{{ liabilityAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Savings transfers in suspense is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Expenses</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Interest on savings</mat-label>
|
||||
<mat-select formControlName="interestOnSavingsAccountId" required>
|
||||
<mat-option *ngFor="let expenseAccount of expenseAccountData" [value]="expenseAccount.id">
|
||||
{{ expenseAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Interest on savings is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Income</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Income from fees</mat-label>
|
||||
<mat-select formControlName="incomeFromFeeAccountId" required>
|
||||
<mat-option *ngFor="let incomeAccount of incomeAccountData" [value]="incomeAccount.id">
|
||||
{{ incomeAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Income from fees Repayments is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Income from penalties</mat-label>
|
||||
<mat-select formControlName="incomeFromPenaltyAccountId" required>
|
||||
<mat-option *ngFor="let incomeAccount of incomeAccountData" [value]="incomeAccount.id">
|
||||
{{ incomeAccount.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Income from penalties is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h3 fxFlex="23%" class="mat-h3">Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-checkbox fxFlex="73%" formControlName="advancedAccountingRules"></mat-checkbox>
|
||||
|
||||
<div *ngIf="fixedDepositProductAccountingForm.value.advancedAccountingRules" fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlex="33%" class="mat-h4">Configure Fund Sources for Payment Channels</h4>
|
||||
|
||||
<div fxFlex="63%">
|
||||
<button type="button" mat-raised-button color="primary" (click)="add('PaymentFundSource', paymentChannelToFundSourceMappings)">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="paymentChannelToFundSourceMappings.value" *ngIf="paymentChannelToFundSourceMappings.value.length !== 0">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentTypeId | find:paymentTypeData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccountId | find:assetAccountData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource; let i = index">
|
||||
<button mat-icon-button color="primary" (click)="edit('PaymentFundSource', paymentChannelToFundSourceMappings, i)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(paymentChannelToFundSourceMappings, i)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h4 fxFlex="33%" class="mat-h4">Map Fees to Specific Income Accounts</h4>
|
||||
|
||||
<div fxFlex="63%">
|
||||
<button type="button" mat-raised-button color="primary" (click)="add('FeesIncome', feeToIncomeAccountMappings)">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="feeToIncomeAccountMappings.value" *ngIf="feeToIncomeAccountMappings.value.length !== 0">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.chargeId | find:chargeData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccountId | find:incomeAccountData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let feesIncome; let i = index">
|
||||
<button mat-icon-button color="primary" (click)="edit('FeesIncome', feeToIncomeAccountMappings, i)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(feeToIncomeAccountMappings, i)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h4 fxFlex="33%" class="mat-h4">Map Penalties to Specific Income Accounts</h4>
|
||||
|
||||
<div fxFlex="63%">
|
||||
<button type="button" mat-raised-button color="primary" (click)="add('PenaltyIncome', penaltyToIncomeAccountMappings)">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="penaltyToIncomeAccountMappings.value" *ngIf="penaltyToIncomeAccountMappings.value.length !== 0">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.chargeId | find:penaltyData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccountId | find:incomeAccountData:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome; let i = index">
|
||||
<button mat-icon-button color="primary" (click)="edit('PenaltyIncome', penaltyToIncomeAccountMappings, i)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(penaltyToIncomeAccountMappings, i)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext [disabled]="!fixedDepositProductFormValid">
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
h3, h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
mat-radio-group, h4 {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
margin: 1em 0 2em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductAccountingStepComponent } from './fixed-deposit-product-accounting-step.component';
|
||||
|
||||
describe('FixedDepositProductAccountingStepComponent', () => {
|
||||
let component: FixedDepositProductAccountingStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductAccountingStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductAccountingStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductAccountingStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, FormArray, Validators, FormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material';
|
||||
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-accounting-step',
|
||||
templateUrl: './fixed-deposit-product-accounting-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-accounting-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductAccountingStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
@Input() accountingRuleData: any;
|
||||
@Input() fixedDepositProductFormValid: boolean;
|
||||
|
||||
fixedDepositProductAccountingForm: FormGroup;
|
||||
|
||||
chargeData: any;
|
||||
penaltyData: any;
|
||||
paymentTypeData: any;
|
||||
assetAccountData: any;
|
||||
incomeAccountData: any;
|
||||
expenseAccountData: any;
|
||||
liabilityAccountData: any;
|
||||
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId', 'actions'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId', 'actions'];
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
public dialog: MatDialog) {
|
||||
this.createfixedDepositProductAccountingForm();
|
||||
this.setConditionalControls();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.chargeData = this.fixedDepositProductsTemplate.chargeOptions || [];
|
||||
this.penaltyData = this.fixedDepositProductsTemplate.penaltyOptions || [];
|
||||
this.paymentTypeData = this.fixedDepositProductsTemplate.paymentTypeOptions || [];
|
||||
this.assetAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||
this.incomeAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions || [];
|
||||
this.expenseAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions || [];
|
||||
this.liabilityAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||
}
|
||||
|
||||
createfixedDepositProductAccountingForm() {
|
||||
this.fixedDepositProductAccountingForm = this.formBuilder.group({
|
||||
'accountingRule': [1]
|
||||
});
|
||||
}
|
||||
|
||||
setConditionalControls() {
|
||||
this.fixedDepositProductAccountingForm.get('accountingRule').valueChanges
|
||||
.subscribe((accountingRule: any) => {
|
||||
if (accountingRule === 2) {
|
||||
this.fixedDepositProductAccountingForm.addControl('savingsReferenceAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('savingsControlAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('transfersInSuspenseAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('interestOnSavingsAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('incomeFromFeeAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('incomeFromPenaltyAccountId', new FormControl('', Validators.required));
|
||||
this.fixedDepositProductAccountingForm.addControl('advancedAccountingRules', new FormControl(false));
|
||||
|
||||
this.fixedDepositProductAccountingForm.get('advancedAccountingRules').valueChanges
|
||||
.subscribe((advancedAccountingRules: boolean) => {
|
||||
if (advancedAccountingRules) {
|
||||
this.fixedDepositProductAccountingForm.addControl('paymentChannelToFundSourceMappings', this.formBuilder.array([]));
|
||||
this.fixedDepositProductAccountingForm.addControl('feeToIncomeAccountMappings', this.formBuilder.array([]));
|
||||
this.fixedDepositProductAccountingForm.addControl('penaltyToIncomeAccountMappings', this.formBuilder.array([]));
|
||||
} else {
|
||||
this.fixedDepositProductAccountingForm.removeControl('paymentChannelToFundSourceMappings');
|
||||
this.fixedDepositProductAccountingForm.removeControl('feeToIncomeAccountMappings');
|
||||
this.fixedDepositProductAccountingForm.removeControl('penaltyToIncomeAccountMappings');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.fixedDepositProductAccountingForm.removeControl('savingsReferenceAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('overdraftPortfolioControlId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('savingsControlAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('transfersInSuspenseAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('interestOnSavingsAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('writeOffAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('incomeFromFeeAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('incomeFromPenaltyAccountId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('incomeFromInterestId');
|
||||
this.fixedDepositProductAccountingForm.removeControl('advancedAccountingRules');
|
||||
this.fixedDepositProductAccountingForm.removeControl('escheatLiabilityId');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get paymentChannelToFundSourceMappings(): FormArray {
|
||||
return this.fixedDepositProductAccountingForm.get('paymentChannelToFundSourceMappings') as FormArray;
|
||||
}
|
||||
|
||||
get feeToIncomeAccountMappings(): FormArray {
|
||||
return this.fixedDepositProductAccountingForm.get('feeToIncomeAccountMappings') as FormArray;
|
||||
}
|
||||
|
||||
get penaltyToIncomeAccountMappings(): FormArray {
|
||||
return this.fixedDepositProductAccountingForm.get('penaltyToIncomeAccountMappings') as FormArray;
|
||||
}
|
||||
|
||||
add(formType: string, formArray: FormArray) {
|
||||
const data = { ...this.getData(formType), pristine: false };
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
formArray.push(response.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
edit(formType: string, formArray: FormArray, index: number) {
|
||||
const data = { ...this.getData(formType, formArray.at(index).value), layout: { addButtonText: 'Edit' } };
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
formArray.at(index).patchValue(response.data.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
delete(formArray: FormArray, index: number) {
|
||||
const dialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `this` }
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
formArray.removeAt(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getData(formType: string, values?: any) {
|
||||
switch (formType) {
|
||||
case 'PaymentFundSource': return { title: 'Configure Fund Sources for Payment Channels', formfields: this.getPaymentFundSourceFormfields(values) };
|
||||
case 'FeesIncome': return { title: 'Map Fees to Income Accounts', formfields: this.getFeesIncomeFormfields(values) };
|
||||
case 'PenaltyIncome': return { title: 'Map Penalties to Specific Income Accounts', formfields: this.getPenaltyIncomeFormfields(values) };
|
||||
}
|
||||
}
|
||||
|
||||
getPaymentFundSourceFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'paymentTypeId',
|
||||
label: 'Payment Type',
|
||||
value: values ? values.paymentTypeId : this.paymentTypeData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.paymentTypeData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'fundSourceAccountId',
|
||||
label: 'Fund Source',
|
||||
value: values ? values.fundSourceAccountId : this.assetAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.assetAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getFeesIncomeFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'chargeId',
|
||||
label: 'Fees',
|
||||
value: values ? values.chargeId : this.chargeData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.chargeData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'incomeAccountId',
|
||||
label: 'Income Account',
|
||||
value: values ? values.incomeAccountId : this.incomeAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.incomeAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
getPenaltyIncomeFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'chargeId',
|
||||
label: 'Penalty',
|
||||
value: values ? values.chargeId : this.penaltyData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.penaltyData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new SelectBase({
|
||||
controlName: 'incomeAccountId',
|
||||
label: 'Income Account',
|
||||
value: values ? values.incomeAccountId : this.incomeAccountData[0].id,
|
||||
options: { label: 'name', value: 'id', data: this.incomeAccountData },
|
||||
required: true,
|
||||
order: 2
|
||||
})
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
get fixedDepositProductAccounting() {
|
||||
return this.fixedDepositProductAccountingForm.value;
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Charge</mat-label>
|
||||
<mat-select #charge>
|
||||
<mat-option *ngFor="let charge of chargeData | chargesFilter:chargesDataSource:currencyCode.value" [value]="charge">
|
||||
{{ charge.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div fxFlex="48%" fxFlexAlign="center">
|
||||
<button type="button" mat-raised-button color="primary" (click)="addCharge(charge)" [disabled]="!charge.value">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chargesDataSource" [hidden]="chargesDataSource.length === 0">
|
||||
|
||||
<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>
|
||||
|
||||
<ng-container matColumnDef="action">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let charge">
|
||||
<button mat-icon-button color="warn" (click)="deleteCharge(charge)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext>
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductChargesStepComponent } from './fixed-deposit-product-charges-step.component';
|
||||
|
||||
describe('FixedDepositProductChargesStepComponent', () => {
|
||||
let component: FixedDepositProductChargesStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductChargesStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductChargesStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductChargesStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-charges-step',
|
||||
templateUrl: './fixed-deposit-product-charges-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-charges-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductChargesStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
@Input() currencyCode: FormControl;
|
||||
|
||||
chargeData: any;
|
||||
|
||||
chargesDataSource: {}[];
|
||||
displayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType', 'action'];
|
||||
|
||||
constructor(public dialog: MatDialog) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.chargeData = this.fixedDepositProductsTemplate.chargeOptions;
|
||||
|
||||
this.chargesDataSource = [];
|
||||
|
||||
this.currencyCode.valueChanges.subscribe(() => this.chargesDataSource = []);
|
||||
}
|
||||
|
||||
addCharge(charge: any) {
|
||||
this.chargesDataSource = this.chargesDataSource.concat([charge.value]);
|
||||
charge.value = '';
|
||||
}
|
||||
|
||||
deleteCharge(charge: any) {
|
||||
const deleteChargeDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `charge ${charge.name}` }
|
||||
});
|
||||
deleteChargeDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
this.chargesDataSource.splice(this.chargesDataSource.indexOf(charge), 1);
|
||||
this.chargesDataSource = this.chargesDataSource.concat([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get fixedDepositProductCharges() {
|
||||
return {
|
||||
charges: this.chargesDataSource
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<form [formGroup]="fixedDepositProductCurrencyForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Currency</mat-label>
|
||||
<mat-select formControlName="currencyCode" required>
|
||||
<mat-option *ngFor="let currency of currencyData" [value]="currency.code">
|
||||
{{ currency.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Currency is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Decimal Places</mat-label>
|
||||
<input type="number" matInput formControlName="digitsAfterDecimal" required>
|
||||
<mat-error>
|
||||
Decimal Places is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Currency in multiples of</mat-label>
|
||||
<input type="number" matInput formControlName="inMultiplesOf" required>
|
||||
<mat-error>
|
||||
Currency in multiples of is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext>
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductCurrencyStepComponent } from './fixed-deposit-product-currency-step.component';
|
||||
|
||||
describe('FixedDepositProductCurrencyStepComponent', () => {
|
||||
let component: FixedDepositProductCurrencyStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductCurrencyStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductCurrencyStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductCurrencyStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-currency-step',
|
||||
templateUrl: './fixed-deposit-product-currency-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-currency-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductCurrencyStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
|
||||
fixedDepositProductCurrencyForm: FormGroup;
|
||||
|
||||
currencyData: any;
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {
|
||||
this.createFixedDepositProductCurrencyForm();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.currencyData = this.fixedDepositProductsTemplate.currencyOptions;
|
||||
|
||||
this.fixedDepositProductCurrencyForm.patchValue({
|
||||
'currencyCode': this.currencyData[0].code,
|
||||
'digitsAfterDecimal': 2
|
||||
});
|
||||
}
|
||||
|
||||
createFixedDepositProductCurrencyForm() {
|
||||
this.fixedDepositProductCurrencyForm = this.formBuilder.group({
|
||||
'currencyCode': ['', Validators.required],
|
||||
'digitsAfterDecimal': ['', Validators.required],
|
||||
'inMultiplesOf': ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
get fixedDepositProductCurrency() {
|
||||
return this.fixedDepositProductCurrencyForm.value;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<form [formGroup]="fixedDepositProductDetailsForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Product Name</mat-label>
|
||||
<input matInput formControlName="name" required>
|
||||
<mat-error>
|
||||
Product Name is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Short Name</mat-label>
|
||||
<input matInput formControlName="shortName" maxlength="4" required>
|
||||
<mat-error>
|
||||
Short Name is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="98%">
|
||||
<mat-label>Description</mat-label>
|
||||
<textarea matInput formControlName="description"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
</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>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductDetailsStepComponent } from './fixed-deposit-product-details-step.component';
|
||||
|
||||
describe('FixedDepositProductDetailsStepComponent', () => {
|
||||
let component: FixedDepositProductDetailsStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductDetailsStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductDetailsStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductDetailsStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-details-step',
|
||||
templateUrl: './fixed-deposit-product-details-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-details-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductDetailsStepComponent implements OnInit {
|
||||
|
||||
fixedDepositProductDetailsForm: FormGroup;
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {
|
||||
this.createFixedDepositProductDetailsForm();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
createFixedDepositProductDetailsForm() {
|
||||
this.fixedDepositProductDetailsForm = this.formBuilder.group({
|
||||
'name': ['', Validators.required],
|
||||
'shortName': ['', Validators.required],
|
||||
'description': ['']
|
||||
});
|
||||
}
|
||||
|
||||
get fixedDepositProductDetails() {
|
||||
return this.fixedDepositProductDetailsForm.value;
|
||||
}
|
||||
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
<form [formGroup]="fixedDepositProductInterestRateChartForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<h3 fxFlex="13%" class="mat-h3">Interest Rate Charts</h3>
|
||||
|
||||
<div fxFlex="83%" fxLayout="row" fxLayoutAlign="start center">
|
||||
<button type="button" mat-raised-button color="primary" (click)="addChart()">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column" formArrayName="charts" *ngFor="let chart of charts.controls; let chartIndex = index">
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" [formGroupName]="chartIndex">
|
||||
|
||||
<div fxFlex="98%" fxLayout="row" fxLayoutAlign="end center">
|
||||
<button type="button" mat-icon-button color="warn" (click)="delete(charts, chartIndex)" matTooltip="Delete Interest Rate Chart" matTooltipPosition="left">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-form-field fxFlex="32%">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput formControlName="name">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-label>Valid from Date</mat-label>
|
||||
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="validFromDatePicker" formControlName="fromDate" required>
|
||||
<mat-datepicker-toggle matSuffix [for]="validFromDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #validFromDatePicker></mat-datepicker>
|
||||
<mat-error>
|
||||
Valid from Date is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-label>End Date</mat-label>
|
||||
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="endDatePicker" formControlName="endDate">
|
||||
<mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #endDatePicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="65%">
|
||||
<mat-label>Description</mat-label>
|
||||
<textarea matInput formControlName="description"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div fxFlex="31%" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<mat-checkbox labelPosition="before" formControlName="isPrimaryGroupingByAmount">
|
||||
Is primary grouping by amount?
|
||||
</mat-checkbox>
|
||||
<button type="button" mat-raised-button color="primary" (click)="addChartSlab(chart.controls.chartSlabs)">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add Slab
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table fxFlex="98%" class="mat-elevation-z1" mat-table [dataSource]="chart.value.chartSlabs" *ngIf="chart.value.chartSlabs.length !== 0" multiTemplateDataRows>
|
||||
|
||||
<ng-container matColumnDef="period">
|
||||
<th mat-header-cell *matHeaderCellDef> Period </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.fromPeriod + ' - ' + chartSlab.toPeriod + ' ' + (chartSlab.periodType | find:periodTypeData:'id':'value') }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amountRange">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount Range </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.amountRangeFrom + ' - ' + chartSlab.amountRangeTo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="annualInterestRate">
|
||||
<th mat-header-cell *matHeaderCellDef> Interest </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.annualInterestRate }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef> Description </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.description }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let chartSlab; let chartSlabIndex = dataIndex">
|
||||
<button mat-icon-button color="primary" (click)="editChartSlab(chart.controls.chartSlabs, chartSlabIndex)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(chart.controls.chartSlabs, chartSlabIndex)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
<button mat-button color="primary" (click)="expandChartSlabIndex[chartIndex] = expandChartSlabIndex[chartIndex] === chartSlabIndex ? null : chartSlabIndex">
|
||||
<span *ngIf="expandChartSlabIndex[chartIndex] !== chartSlabIndex">
|
||||
<fa-icon icon="eye"></fa-icon>
|
||||
View Incentives
|
||||
</span>
|
||||
<span *ngIf="expandChartSlabIndex[chartIndex] === chartSlabIndex">
|
||||
<fa-icon icon="eye-slash"></fa-icon>
|
||||
Hide Incentives
|
||||
</span>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incentives">
|
||||
<td mat-cell *matCellDef="let chartSlab; let chartSlabIndex = dataIndex" [attr.colspan]="chartSlabsDisplayedColumns[chartIndex].length">
|
||||
|
||||
<div fxLayout="row wrap" fxFlexFill class="incentives" [@expandChartSlab]="chartSlabIndex === expandChartSlabIndex[chartIndex] ? 'expanded' : 'collapsed'">
|
||||
|
||||
<mat-card fxLayout="row wrap" fxFlexFill>
|
||||
|
||||
<h4 class="mat-h4" fxFlex="13%">
|
||||
Incentives
|
||||
</h4>
|
||||
|
||||
<div fxFlex="83%">
|
||||
<button mat-raised-button color="primary" (click)="addIncentive(getIncentives(chart.controls.chartSlabs, chartSlabIndex))">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="chartSlab.incentives" *ngIf="chartSlab.incentives.length">
|
||||
|
||||
<ng-container matColumnDef="entityType">
|
||||
<th mat-header-cell *matHeaderCellDef> Entity Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.entityType | find:entityTypeData:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attributeName">
|
||||
<th mat-header-cell *matHeaderCellDef> Attribute Name </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.attributeName | find:attributeNameData:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="conditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.conditionType | find:conditionTypeData:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attributeValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Attribute Value </th>
|
||||
<td mat-cell *matCellDef="let incentive" [ngSwitch]="incentive.attributeName">
|
||||
<span *ngSwitchCase="2">{{ incentive.attributeValue | find:genderData:'id':'name' }}</span>
|
||||
<span *ngSwitchCase="3">{{ incentive.attributeValue }}</span>
|
||||
<span *ngSwitchCase="4">{{ incentive.attributeValue | find:clientTypeData:'id':'name' }}</span>
|
||||
<span *ngSwitchCase="5">{{ incentive.attributeValue | find:clientClassificationData:'id':'name' }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incentiveType">
|
||||
<th mat-header-cell *matHeaderCellDef> Incentive Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.incentiveType | find:incentiveTypeData:'id':'value'}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Interest </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let incentive; let incentiveIndex = index">
|
||||
<button mat-icon-button color="primary" (click)="editIncentive(getIncentives(chart.controls.chartSlabs, chartSlabIndex), incentiveIndex)">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="delete(getIncentives(chart.controls.chartSlabs, chartSlabIndex), incentiveIndex)">
|
||||
<fa-icon icon="trash"></fa-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="incentivesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: incentivesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</mat-card>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chartSlabsDisplayedColumns[chartIndex]"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chartSlabsDisplayedColumns[chartIndex];"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chartSlabsIncentivesDisplayedColumns;" class="incentives-row"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</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>
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
tr.incentives-row {
|
||||
height: 0;
|
||||
|
||||
> td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.incentives {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mat-card {
|
||||
border-radius: 0;
|
||||
|
||||
> h4 {
|
||||
margin: 0.5em 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
margin: 1em 0 1em 0;
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
h3, h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h3, h4 {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.margin-v {
|
||||
margin: 1em 0;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductInterestRateChartStepComponent } from './fixed-deposit-product-interest-rate-chart-step.component';
|
||||
|
||||
describe('FixedDepositProductInterestRateChartStepComponent', () => {
|
||||
let component: FixedDepositProductInterestRateChartStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductInterestRateChartStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductInterestRateChartStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductInterestRateChartStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators, FormArray } from '@angular/forms';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { DepositProductIncentiveFormDialogComponent } from 'app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component';
|
||||
import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component';
|
||||
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-interest-rate-chart-step',
|
||||
templateUrl: './fixed-deposit-product-interest-rate-chart-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-interest-rate-chart-step.component.scss'],
|
||||
animations: [
|
||||
trigger('expandChartSlab', [
|
||||
state('collapsed', style({ height: '0px', minHeight: '0' })),
|
||||
state('expanded', style({ height: '*' })),
|
||||
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class FixedDepositProductInterestRateChartStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
|
||||
fixedDepositProductInterestRateChartForm: FormGroup;
|
||||
|
||||
periodTypeData: any;
|
||||
entityTypeData: any;
|
||||
attributeNameData: any;
|
||||
conditionTypeData: any;
|
||||
genderData: any;
|
||||
clientTypeData: any;
|
||||
clientClassificationData: any;
|
||||
incentiveTypeData: any;
|
||||
|
||||
chartSlabsDisplayedColumns: any[] = [];
|
||||
chartSlabsIncentivesDisplayedColumns: string[] = ['incentives'];
|
||||
incentivesDisplayedColumns: string[] = ['entityType', 'attributeName', 'conditionType', 'attributeValue', 'incentiveType', 'amount', 'actions'];
|
||||
|
||||
minDate = new Date(2000, 0, 1);
|
||||
maxDate = new Date(new Date().setFullYear(new Date().getFullYear() + 10));
|
||||
|
||||
expandChartSlabIndex: number[] = [];
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
public dialog: MatDialog,
|
||||
private datePipe: DatePipe) {
|
||||
this.createFixedDepositProductInterestRateChartForm();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.periodTypeData = this.fixedDepositProductsTemplate.chartTemplate.periodTypes;
|
||||
this.entityTypeData = this.fixedDepositProductsTemplate.chartTemplate.entityTypeOptions;
|
||||
this.attributeNameData = this.fixedDepositProductsTemplate.chartTemplate.attributeNameOptions;
|
||||
this.conditionTypeData = this.fixedDepositProductsTemplate.chartTemplate.conditionTypeOptions;
|
||||
this.genderData = this.fixedDepositProductsTemplate.chartTemplate.genderOptions;
|
||||
this.clientTypeData = this.fixedDepositProductsTemplate.chartTemplate.clientTypeOptions;
|
||||
this.clientClassificationData = this.fixedDepositProductsTemplate.chartTemplate.clientClassificationOptions;
|
||||
this.incentiveTypeData = this.fixedDepositProductsTemplate.chartTemplate.incentiveTypeOptions;
|
||||
}
|
||||
|
||||
createFixedDepositProductInterestRateChartForm() {
|
||||
this.fixedDepositProductInterestRateChartForm = this.formBuilder.group({
|
||||
'charts': this.formBuilder.array([])
|
||||
});
|
||||
}
|
||||
|
||||
get charts(): FormArray {
|
||||
return this.fixedDepositProductInterestRateChartForm.get('charts') as FormArray;
|
||||
}
|
||||
|
||||
createChartForm(): FormGroup {
|
||||
return this.formBuilder.group({
|
||||
'name': [''],
|
||||
'description': [''],
|
||||
'fromDate': ['', Validators.required],
|
||||
'endDate': [''],
|
||||
'isPrimaryGroupingByAmount': [false],
|
||||
'chartSlabs': this.formBuilder.array([])
|
||||
});
|
||||
}
|
||||
|
||||
addChart() {
|
||||
this.charts.push(this.createChartForm());
|
||||
this.setConditionalControls(this.charts.length - 1);
|
||||
}
|
||||
|
||||
setConditionalControls(chartIndex: number) {
|
||||
this.chartSlabsDisplayedColumns[chartIndex] = ['period', 'amountRange', 'annualInterestRate', 'description', 'actions'];
|
||||
this.charts.at(chartIndex).get('isPrimaryGroupingByAmount').valueChanges
|
||||
.subscribe((isPrimaryGroupingByAmount: boolean) => {
|
||||
this.chartSlabsDisplayedColumns[chartIndex] = isPrimaryGroupingByAmount ? ['amountRange', 'period'] : ['period', 'amountRange'];
|
||||
this.chartSlabsDisplayedColumns[chartIndex].push('annualInterestRate', 'description', 'actions');
|
||||
});
|
||||
}
|
||||
|
||||
getIncentives(chartSlabs: FormArray, chartSlabIndex: number): FormArray {
|
||||
return chartSlabs.at(chartSlabIndex).get('incentives') as FormArray;
|
||||
}
|
||||
|
||||
addChartSlab(chartSlabs: FormArray) {
|
||||
const data = { ...this.getData('Slab') };
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
response.data.addControl('incentives', this.formBuilder.array([]));
|
||||
chartSlabs.push(response.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addIncentive(incentives: FormArray) {
|
||||
const data = { ...this.getData('Incentive'), entityType: this.entityTypeData[0].id };
|
||||
const dialogRef = this.dialog.open(DepositProductIncentiveFormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
incentives.push(response.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editChartSlab(chartSlabs: FormArray, chartSlabIndex: number) {
|
||||
const data = { ...this.getData('Slab', chartSlabs.at(chartSlabIndex).value), layout: { addButtonText: 'Edit' } };
|
||||
const dialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
chartSlabs.at(chartSlabIndex).patchValue(response.data.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editIncentive(incentives: FormArray, incentiveIndex: number) {
|
||||
const data = { ...this.getData('Incentive', incentives.at(incentiveIndex).value), layout: { addButtonText: 'Edit' } };
|
||||
const dialogRef = this.dialog.open(DepositProductIncentiveFormDialogComponent, { data });
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
incentives.at(incentiveIndex).patchValue(response.data.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
delete(formArray: FormArray, index: number) {
|
||||
const dialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `this` }
|
||||
});
|
||||
dialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
formArray.removeAt(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getData(formType: string, values?: any) {
|
||||
switch (formType) {
|
||||
case 'Slab': return { title: 'Slab', formfields: this.getSlabFormfields(values) };
|
||||
case 'Incentive': return { values, chartTemplate: this.fixedDepositProductsTemplate.chartTemplate };
|
||||
}
|
||||
}
|
||||
|
||||
getSlabFormfields(values?: any) {
|
||||
const formfields: FormfieldBase[] = [
|
||||
new SelectBase({
|
||||
controlName: 'periodType',
|
||||
label: 'Period Type',
|
||||
value: values ? values.periodType : this.periodTypeData[0].id,
|
||||
options: { label: 'value', value: 'id', data: this.periodTypeData },
|
||||
required: true,
|
||||
order: 1
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'fromPeriod',
|
||||
label: 'Period From',
|
||||
value: values ? values.fromPeriod : undefined,
|
||||
type: 'number',
|
||||
required: true,
|
||||
order: 2
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'toPeriod',
|
||||
label: 'Period To',
|
||||
value: values ? values.toPeriod : undefined,
|
||||
type: 'number',
|
||||
order: 3
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'amountRangeFrom',
|
||||
label: 'Amount Range From',
|
||||
value: values ? values.amountRangeFrom : undefined,
|
||||
type: 'number',
|
||||
order: 4
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'amountRangeTo',
|
||||
label: 'Amount Range To',
|
||||
value: values ? values.amountRangeTo : undefined,
|
||||
type: 'number',
|
||||
order: 5
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'annualInterestRate',
|
||||
label: 'Interest',
|
||||
value: values ? values.annualInterestRate : undefined,
|
||||
type: 'number',
|
||||
required: true,
|
||||
order: 6
|
||||
}),
|
||||
new InputBase({
|
||||
controlName: 'description',
|
||||
label: 'Description',
|
||||
value: values ? values.description : undefined,
|
||||
required: true,
|
||||
order: 7
|
||||
})
|
||||
];
|
||||
return formfields;
|
||||
}
|
||||
|
||||
get fixedDepositProductInterestRateChart() {
|
||||
// TODO: Update once language and date settings are setup
|
||||
const dateFormat = 'yyyy-MM-dd';
|
||||
const locale = 'en';
|
||||
const fixedDepositProductInterestRateChart = this.fixedDepositProductInterestRateChartForm.value;
|
||||
for (const chart of fixedDepositProductInterestRateChart.charts) {
|
||||
chart.dateFormat = dateFormat;
|
||||
chart.locale = locale;
|
||||
chart.fromDate = this.datePipe.transform(chart.fromDate, dateFormat) || '';
|
||||
chart.endDate = this.datePipe.transform(chart.endDate, dateFormat) || '';
|
||||
if (chart.endDate === '') {
|
||||
delete chart.endDate;
|
||||
}
|
||||
}
|
||||
return fixedDepositProductInterestRateChart;
|
||||
}
|
||||
|
||||
}
|
||||
+460
@@ -0,0 +1,460 @@
|
||||
<div fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h2 class="mat-h2" fxFlexFill>{{ fixedDepositProduct.name }}</h2>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Details</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Short Name:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.shortName }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.description }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Currency</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.currencyCode | find:fixedDepositProductsTemplate.currencyOptions:'code':'name' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Decimal Places:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.digitsAfterDecimal }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Currency in multiples of:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.inMultiplesOf }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Terms</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Deposit Amount:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.depositAmount + ' (Min: ' + (fixedDepositProduct.minDepositAmount ? fixedDepositProduct.minDepositAmount : fixedDepositProduct.depositAmount) + ', Max: ' + (fixedDepositProduct.maxDepositAmount ? fixedDepositProduct.maxDepositAmount : fixedDepositProduct.depositAmount) + ')' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Compounding Period:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.interestCompoundingPeriodType | find:fixedDepositProductsTemplate.interestCompoundingPeriodTypeOptions:'id':'value' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Posting Period:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.interestPostingPeriodType | find:fixedDepositProductsTemplate.interestPostingPeriodTypeOptions:'id':'value' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest Calculated using:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.interestCalculationType | find:fixedDepositProductsTemplate.interestCalculationTypeOptions:'id':'value' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Days in Year:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.interestCalculationDaysInYearType | find:fixedDepositProductsTemplate.interestCalculationDaysInYearTypeOptions:'id':'value' }}</span>
|
||||
</div>
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Settings</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.lockinPeriodFrequency">
|
||||
<span fxFlex="40%">Lock-in Period:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.lockinPeriodFrequency + ' ' + (fixedDepositProduct.lockinPeriodFrequencyType | find:fixedDepositProductsTemplate.lockinPeriodFrequencyTypeOptions:'id':'value') }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Minimum Deposit Term:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.minDepositTerm + ' ' + (fixedDepositProduct.minDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.inMultiplesOfDepositTerm">
|
||||
<span fxFlex="40%">And thereafter, in Multiples of:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.inMultiplesOfDepositTerm + ' ' + (fixedDepositProduct.inMultiplesOfDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.maxDepositTerm">
|
||||
<span fxFlex="40%">Minimum Deposit Term:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.maxDepositTerm + ' ' + (fixedDepositProduct.maxDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }}</span>
|
||||
</div>
|
||||
<!-- For Pre-mature closure -->
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Apply Penal Interest (less):</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.preClosurePenalApplicable ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.preClosurePenalApplicable">
|
||||
<span fxFlex="40%">Penal Interest (%):</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.preClosurePenalInterest + '% (' + (fixedDepositProduct.preClosurePenalInterestOnTypeId | find:fixedDepositProductsTemplate.preClosurePenalInterestOnTypeOptions:'id':'value') + ')' }}</span>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Withhold Tax is Applicable:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.withHoldTax ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.withHoldTax">
|
||||
<span fxFlex="40%">Tax Group:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.taxGroupId | find:fixedDepositProductsTemplate.taxGroupOptions:'id':'name' }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column" *ngIf="fixedDepositProduct.charts.length !== 0">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Interest Rate Charts</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill *ngFor="let chart of fixedDepositProduct.charts; let chartIndex = index" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<div fxFlexFill *ngIf="chart.name">
|
||||
<span fxFlex="40%">Name:</span>
|
||||
<span fxFlex="60%">{{ chart.name }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Valid from Date:</span>
|
||||
<span fxFlex="60%">{{ chart.fromDate | date }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="chart.endDate">
|
||||
<span fxFlex="40%">End Date:</span>
|
||||
<span fxFlex="60%">{{ chart.endDate | date }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="chart.description">
|
||||
<span fxFlex="40%">Description:</span>
|
||||
<span fxFlex="60%">{{ chart.description }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Primary Grouping by Amount:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.isPrimaryGroupingByAmount ? 'Yes' : 'No' }}</span>
|
||||
</div>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="chart.chartSlabs" *ngIf="chart.chartSlabs.length !== 0" multiTemplateDataRows>
|
||||
|
||||
<ng-container matColumnDef="period">
|
||||
<th mat-header-cell *matHeaderCellDef> Period </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.fromPeriod + ' - ' + chartSlab.toPeriod + ' ' + (chartSlab.periodType | find:fixedDepositProductsTemplate.chartTemplate.periodTypes:'id':'value') }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amountRange">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount Range </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.amountRangeFrom + ' - ' + chartSlab.amountRangeTo }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="annualInterestRate">
|
||||
<th mat-header-cell *matHeaderCellDef> Interest </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.annualInterestRate }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell *matHeaderCellDef> Description </th>
|
||||
<td mat-cell *matCellDef="let chartSlab">
|
||||
{{ chartSlab.description }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Actions </th>
|
||||
<td mat-cell *matCellDef="let chartSlab; let chartSlabIndex = dataIndex">
|
||||
<button mat-button color="primary" (click)="expandChartSlabIndex[chartIndex] = expandChartSlabIndex[chartIndex] === chartSlabIndex ? null : chartSlabIndex" [disabled]="chartSlab.incentives.length === 0">
|
||||
<span *ngIf="expandChartSlabIndex[chartIndex] !== chartSlabIndex">
|
||||
<fa-icon icon="eye"></fa-icon>
|
||||
View Incentives
|
||||
</span>
|
||||
<span *ngIf="expandChartSlabIndex[chartIndex] === chartSlabIndex">
|
||||
<fa-icon icon="eye-slash"></fa-icon>
|
||||
Hide Incentives
|
||||
</span>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incentives">
|
||||
<td mat-cell *matCellDef="let chartSlab; let chartSlabIndex = dataIndex" [attr.colspan]="chartSlabsDisplayedColumns[chartIndex].length">
|
||||
<div fxLayout="row wrap" fxFlexFill class="incentives" [@expandChartSlab]="chartSlabIndex === expandChartSlabIndex[chartIndex] ? 'expanded' : 'collapsed'">
|
||||
<mat-card fxLayout="row wrap" fxFlexFill>
|
||||
|
||||
<h4 class="mat-h4" fxFlex="23%">
|
||||
Incentives
|
||||
</h4>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="chartSlab.incentives">
|
||||
|
||||
<ng-container matColumnDef="entityType">
|
||||
<th mat-header-cell *matHeaderCellDef> Entity Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.entityType | find:fixedDepositProductsTemplate.chartTemplate.entityTypeOptions:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attributeName">
|
||||
<th mat-header-cell *matHeaderCellDef> Attribute Name </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.attributeName | find:fixedDepositProductsTemplate.chartTemplate.attributeNameOptions:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="conditionType">
|
||||
<th mat-header-cell *matHeaderCellDef> Condition Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.conditionType | find:fixedDepositProductsTemplate.chartTemplate.conditionTypeOptions:'id':'value' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attributeValue">
|
||||
<th mat-header-cell *matHeaderCellDef> Attribute Value </th>
|
||||
<td mat-cell *matCellDef="let incentive" [ngSwitch]="incentive.attributeName">
|
||||
<span *ngSwitchCase="2">{{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.genderOptions:'id':'name' }}</span>
|
||||
<span *ngSwitchCase="3">{{ incentive.attributeValue }}</span>
|
||||
<span *ngSwitchCase="4">{{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.clientTypeOptions:'id':'name' }}</span>
|
||||
<span *ngSwitchCase="5">{{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.clientClassificationOptions:'id':'name' }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incentiveType">
|
||||
<th mat-header-cell *matHeaderCellDef> Incentive Type </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.incentiveType | find:fixedDepositProductsTemplate.chartTemplate.incentiveTypeOptions:'id':'value'}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef> Amount </th>
|
||||
<td mat-cell *matCellDef="let incentive">
|
||||
{{ incentive.amount }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="incentivesDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: incentivesDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</mat-card>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="chartSlabsDisplayedColumns[chartIndex]"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chartSlabsDisplayedColumns[chartIndex];"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: chartSlabsIncentivesDisplayedColumns;" class="incentives-row"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.charges.length" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Charges</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<table fxFlexFill class="mat-elevation-z1" mat-table [dataSource]="fixedDepositProduct.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 fxFlexFill></mat-divider>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Type:</span>
|
||||
<span fxFlex="60%">{{ accountingRuleData[fixedDepositProduct.accountingRule-1] }}</span>
|
||||
</div>
|
||||
|
||||
<div fxFlexFill *ngIf="fixedDepositProduct.accountingRule === 2" fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Assets</h4>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Saving reference:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.savingsReferenceAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'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%">{{ fixedDepositProduct.savingsControlAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }}</span>
|
||||
<span fxFlex="40%">Savings transfers in suspense:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.transfersInSuspenseAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }}</span>
|
||||
</div>
|
||||
|
||||
<h4 fxFlexFill class="mat-h4">Expenses</h4>
|
||||
|
||||
<div fxFlexFill>
|
||||
<span fxFlex="40%">Interest on savings:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.interestOnSavingsAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'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%">{{ fixedDepositProduct.incomeFromFeeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }}</span>
|
||||
<span fxFlex="40%">Income from penalties:</span>
|
||||
<span fxFlex="60%">{{ fixedDepositProduct.incomeFromPenaltyAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="fixedDepositProduct.advancedAccountingRules && (fixedDepositProduct.paymentChannelToFundSourceMappings?.length || fixedDepositProduct.feeToIncomeAccountMappings?.length || fixedDepositProduct.penaltyToIncomeAccountMappings?.length)" fxFlexFill fxLayout="row wrap" fxLayout.lt-md="column">
|
||||
|
||||
<h3 class="mat-h3" fxFlexFill>Advanced Accounting Rules</h3>
|
||||
|
||||
<mat-divider fxFlexFill></mat-divider>
|
||||
|
||||
<div *ngIf="fixedDepositProduct.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]="fixedDepositProduct.paymentChannelToFundSourceMappings">
|
||||
|
||||
<ng-container matColumnDef="paymentTypeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Payment Type </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.paymentTypeId | find:fixedDepositProductsTemplate.paymentTypeOptions:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="fundSourceAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fund Source </th>
|
||||
<td mat-cell *matCellDef="let paymentFundSource">
|
||||
{{ paymentFundSource.fundSourceAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="paymentFundSourceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: paymentFundSourceDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="fixedDepositProduct.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]="fixedDepositProduct.feeToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Fees </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.chargeId | find:fixedDepositProductsTemplate.chargeOptions:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let feesIncome">
|
||||
{{ feesIncome.incomeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="feesPenaltyIncomeDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: feesPenaltyIncomeDisplayedColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="fixedDepositProduct.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]="fixedDepositProduct.penaltyToIncomeAccountMappings">
|
||||
|
||||
<ng-container matColumnDef="chargeId">
|
||||
<th mat-header-cell *matHeaderCellDef> Penalty </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.chargeId | find:fixedDepositProductsTemplate.penaltyOptions:'id':'name' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="incomeAccountId">
|
||||
<th mat-header-cell *matHeaderCellDef> Income Account </th>
|
||||
<td mat-cell *matCellDef="let penaltyIncome">
|
||||
{{ penaltyIncome.incomeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'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>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button [routerLink]="['../']">
|
||||
Cancel
|
||||
</button>
|
||||
<button mat-raised-button color="primary" (click)="submit.emit()">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
tr.incentives-row {
|
||||
height: 0;
|
||||
|
||||
> td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.incentives {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mat-card {
|
||||
border-radius: 0;
|
||||
|
||||
> h4 {
|
||||
font-weight: 500;
|
||||
margin: 0.5em 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-elevation-z1 {
|
||||
margin: 1em 0 1.5em 0;
|
||||
}
|
||||
|
||||
h2, h3, h4 {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductPreviewStepComponent } from './fixed-deposit-product-preview-step.component';
|
||||
|
||||
describe('FixedDepositProductPreviewStepComponent', () => {
|
||||
let component: FixedDepositProductPreviewStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductPreviewStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductPreviewStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductPreviewStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { trigger, state, transition, animate, style } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-preview-step',
|
||||
templateUrl: './fixed-deposit-product-preview-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-preview-step.component.scss'],
|
||||
animations: [
|
||||
trigger('expandChartSlab', [
|
||||
state('collapsed', style({height: '0px', minHeight: '0'})),
|
||||
state('expanded', style({height: '*'})),
|
||||
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class FixedDepositProductPreviewStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
@Input() chartSlabsDisplayedColumns: any[];
|
||||
@Input() accountingRuleData: any;
|
||||
@Input() fixedDepositProduct: any;
|
||||
@Output() submit = new EventEmitter();
|
||||
|
||||
chartSlabsIncentivesDisplayedColumns: string[] = ['incentives'];
|
||||
incentivesDisplayedColumns: string[] = ['entityType', 'attributeName', 'conditionType', 'attributeValue', 'incentiveType', 'amount'];
|
||||
chargesDisplayedColumns: string[] = ['name', 'chargeCalculationType', 'amount', 'chargeTimeType'];
|
||||
paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId'];
|
||||
feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId'];
|
||||
|
||||
expandChartSlabIndex: number[] = [];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
<form [formGroup]="fixedDepositProductSettingsForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Lock-in Period</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Frequency</mat-label>
|
||||
<input type="number" matInput formControlName="lockinPeriodFrequency">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="lockinPeriodFrequencyType">
|
||||
<mat-option *ngFor="let lockinPeriodFrequencyType of lockinPeriodFrequencyTypeData" [value]="lockinPeriodFrequencyType.id">
|
||||
{{ lockinPeriodFrequencyType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Minimum Deposit Term</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Frequency</mat-label>
|
||||
<input type="number" matInput formControlName="minDepositTerm" required>
|
||||
<mat-error>
|
||||
Minimum Deposit Term Frequency is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Frequency Type</mat-label>
|
||||
<mat-select formControlName="minDepositTermTypeId" required>
|
||||
<mat-option *ngFor="let periodFrequencyType of periodFrequencyTypeData" [value]="periodFrequencyType.id">
|
||||
{{ periodFrequencyType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Minimum Deposit Term Frequency Type is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">And thereafter, in Multiples of</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Frequency</mat-label>
|
||||
<input type="number" matInput formControlName="inMultiplesOfDepositTerm">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="inMultiplesOfDepositTermTypeId">
|
||||
<mat-option *ngFor="let periodFrequencyType of periodFrequencyTypeData" [value]="periodFrequencyType.id">
|
||||
{{ periodFrequencyType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Maximum Deposit Term</h4>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Frequency</mat-label>
|
||||
<input type="number" matInput formControlName="maxDepositTerm">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="maxDepositTermTypeId">
|
||||
<mat-option *ngFor="let periodFrequencyType of periodFrequencyTypeData" [value]="periodFrequencyType.id">
|
||||
{{ periodFrequencyType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h4 fxFlex="23%" class="mat-h4">For Pre-mature closure</h4>
|
||||
|
||||
<mat-checkbox fxFlex="73%" labelPosition="before" formControlName="preClosurePenalApplicable" class="margin-v">
|
||||
Apply Penal Interest (less)
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Penal Interest (%)</mat-label>
|
||||
<input type="number" matInput formControlName="preClosurePenalInterest">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Period</mat-label>
|
||||
<mat-select formControlName="preClosurePenalInterestOnTypeId">
|
||||
<mat-option *ngFor="let preClosurePenalInterestOnType of preClosurePenalInterestOnTypeData" [value]="preClosurePenalInterestOnType.id">
|
||||
{{ preClosurePenalInterestOnType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<mat-checkbox fxFlex="48%" labelPosition="before" formControlName="withHoldTax" class="margin-v">
|
||||
Is Withhold Tax Applicable?
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field fxFlex="48%" *ngIf="fixedDepositProductSettingsForm.value.withHoldTax">
|
||||
<mat-label>Tax Group</mat-label>
|
||||
<mat-select formControlName="taxGroupId" required>
|
||||
<mat-option *ngFor="let taxGroup of taxGroupData" [value]="taxGroup.id">
|
||||
{{ taxGroup.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Tax Group is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext>
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
h4 {
|
||||
font-weight: 500;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
margin: 1em 0 2em 0;
|
||||
}
|
||||
|
||||
.margin-v {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.margin-b {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductSettingsStepComponent } from './fixed-deposit-product-settings-step.component';
|
||||
|
||||
describe('FixedDepositProductSettingsStepComponent', () => {
|
||||
let component: FixedDepositProductSettingsStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductSettingsStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductSettingsStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductSettingsStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-settings-step',
|
||||
templateUrl: './fixed-deposit-product-settings-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-settings-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductSettingsStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
|
||||
fixedDepositProductSettingsForm: FormGroup;
|
||||
|
||||
lockinPeriodFrequencyTypeData: any;
|
||||
periodFrequencyTypeData: any;
|
||||
preClosurePenalInterestOnTypeData: any;
|
||||
taxGroupData: any;
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {
|
||||
this.createFixedDepositProductSettingsForm();
|
||||
this.setConditionalControls();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.lockinPeriodFrequencyTypeData = this.fixedDepositProductsTemplate.lockinPeriodFrequencyTypeOptions;
|
||||
this.periodFrequencyTypeData = this.fixedDepositProductsTemplate.periodFrequencyTypeOptions.slice(0, -1);
|
||||
this.preClosurePenalInterestOnTypeData = this.fixedDepositProductsTemplate.preClosurePenalInterestOnTypeOptions;
|
||||
this.taxGroupData = this.fixedDepositProductsTemplate.taxGroupOptions;
|
||||
}
|
||||
|
||||
createFixedDepositProductSettingsForm() {
|
||||
this.fixedDepositProductSettingsForm = this.formBuilder.group({
|
||||
'lockinPeriodFrequency': [''],
|
||||
'lockinPeriodFrequencyType': [''],
|
||||
'minDepositTerm': ['', Validators.required],
|
||||
'minDepositTermTypeId': ['', Validators.required],
|
||||
'inMultiplesOfDepositTerm': [''],
|
||||
'inMultiplesOfDepositTermTypeId': [''],
|
||||
'maxDepositTerm': [''],
|
||||
'maxDepositTermTypeId': [''],
|
||||
'preClosurePenalApplicable': [false],
|
||||
'preClosurePenalInterest': [''],
|
||||
'preClosurePenalInterestOnTypeId': [''],
|
||||
'withHoldTax': [false]
|
||||
});
|
||||
}
|
||||
|
||||
setConditionalControls() {
|
||||
this.fixedDepositProductSettingsForm.get('withHoldTax').valueChanges
|
||||
.subscribe((withHoldTax: any) => {
|
||||
if (withHoldTax) {
|
||||
this.fixedDepositProductSettingsForm.addControl('taxGroupId', new FormControl('', Validators.required));
|
||||
} else {
|
||||
this.fixedDepositProductSettingsForm.removeControl('taxGroupId');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get fixedDepositProductSettings() {
|
||||
const fixedDepositProductSettings = this.fixedDepositProductSettingsForm.value;
|
||||
for (const key in fixedDepositProductSettings) {
|
||||
if (fixedDepositProductSettings[key] === '') {
|
||||
delete fixedDepositProductSettings[key];
|
||||
}
|
||||
}
|
||||
return fixedDepositProductSettings;
|
||||
}
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<form [formGroup]="fixedDepositProductTermsForm">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<h4 fxFlex="98%" class="mat-h4">Deposit Amount</h4>
|
||||
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-label>Minimum</mat-label>
|
||||
<input type="number" matInput formControlName="minDepositAmount">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-label>Default</mat-label>
|
||||
<input type="number" matInput formControlName="depositAmount" required>
|
||||
<mat-error>
|
||||
Default Deposit Amount is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-label>Maximum</mat-label>
|
||||
<input type="number" matInput formControlName="maxDepositAmount">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Interest Compounding Period</mat-label>
|
||||
<mat-select formControlName="interestCompoundingPeriodType" required>
|
||||
<mat-option *ngFor="let interestCompoundingPeriodType of interestCompoundingPeriodTypeData" [value]="interestCompoundingPeriodType.id">
|
||||
{{ interestCompoundingPeriodType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Interest Compounding Period is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Interest Posting Period</mat-label>
|
||||
<mat-select formControlName="interestPostingPeriodType" required>
|
||||
<mat-option *ngFor="let interestPostingPeriodType of interestPostingPeriodTypeData" [value]="interestPostingPeriodType.id">
|
||||
{{ interestPostingPeriodType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Interest Posting Period is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Interest Calculated using</mat-label>
|
||||
<mat-select formControlName="interestCalculationType" required>
|
||||
<mat-option *ngFor="let interestCalculationType of interestCalculationTypeData" [value]="interestCalculationType.id">
|
||||
{{ interestCalculationType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Interest Calculated using is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Days in Year</mat-label>
|
||||
<mat-select formControlName="interestCalculationDaysInYearType" required>
|
||||
<mat-option *ngFor="let interestCalculationDaysInYearType of interestCalculationDaysInYearTypeData" [value]="interestCalculationDaysInYearType.id">
|
||||
{{ interestCalculationDaysInYearType.value }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error>
|
||||
Days in Year is <strong>required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="margin-t" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||
<button mat-raised-button matStepperPrevious>
|
||||
<fa-icon icon="arrow-left"></fa-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button mat-raised-button matStepperNext>
|
||||
Next
|
||||
<fa-icon icon="arrow-right"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
h4 {
|
||||
font-weight: 500;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
margin: 1em 0 2em 0;
|
||||
}
|
||||
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FixedDepositProductTermsStepComponent } from './fixed-deposit-product-terms-step.component';
|
||||
|
||||
describe('FixedDepositProductTermsStepComponent', () => {
|
||||
let component: FixedDepositProductTermsStepComponent;
|
||||
let fixture: ComponentFixture<FixedDepositProductTermsStepComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FixedDepositProductTermsStepComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FixedDepositProductTermsStepComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-fixed-deposit-product-terms-step',
|
||||
templateUrl: './fixed-deposit-product-terms-step.component.html',
|
||||
styleUrls: ['./fixed-deposit-product-terms-step.component.scss']
|
||||
})
|
||||
export class FixedDepositProductTermsStepComponent implements OnInit {
|
||||
|
||||
@Input() fixedDepositProductsTemplate: any;
|
||||
|
||||
fixedDepositProductTermsForm: FormGroup;
|
||||
|
||||
interestCompoundingPeriodTypeData: any;
|
||||
interestPostingPeriodTypeData: any;
|
||||
interestCalculationTypeData: any;
|
||||
interestCalculationDaysInYearTypeData: any;
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {
|
||||
this.createFixedDepositProductTermsForm();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.interestCompoundingPeriodTypeData = this.fixedDepositProductsTemplate.interestCompoundingPeriodTypeOptions;
|
||||
this.interestPostingPeriodTypeData = this.fixedDepositProductsTemplate.interestPostingPeriodTypeOptions;
|
||||
this.interestCalculationTypeData = this.fixedDepositProductsTemplate.interestCalculationTypeOptions;
|
||||
this.interestCalculationDaysInYearTypeData = this.fixedDepositProductsTemplate.interestCalculationDaysInYearTypeOptions;
|
||||
|
||||
this.fixedDepositProductTermsForm.patchValue({
|
||||
'interestCompoundingPeriodType': this.fixedDepositProductsTemplate.interestCompoundingPeriodType.id,
|
||||
'interestPostingPeriodType': this.fixedDepositProductsTemplate.interestPostingPeriodType.id,
|
||||
'interestCalculationType': this.fixedDepositProductsTemplate.interestCalculationType.id,
|
||||
'interestCalculationDaysInYearType': this.fixedDepositProductsTemplate.interestCalculationDaysInYearType.id
|
||||
});
|
||||
}
|
||||
|
||||
createFixedDepositProductTermsForm() {
|
||||
this.fixedDepositProductTermsForm = this.formBuilder.group({
|
||||
'minDepositAmount': [''],
|
||||
'depositAmount': ['', Validators.required],
|
||||
'maxDepositAmount': [''],
|
||||
'interestCompoundingPeriodType': ['', Validators.required],
|
||||
'interestPostingPeriodType': ['', Validators.required],
|
||||
'interestCalculationType': ['', Validators.required],
|
||||
'interestCalculationDaysInYearType': ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
get fixedDepositProductTerms() {
|
||||
const fixedDepositProductTerms = this.fixedDepositProductTermsForm.value;
|
||||
for (const key in fixedDepositProductTerms) {
|
||||
if (fixedDepositProductTerms[key] === '') {
|
||||
delete fixedDepositProductTerms[key];
|
||||
}
|
||||
}
|
||||
return fixedDepositProductTerms;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/** Custom Services */
|
||||
import { ProductsService } from '../products.service';
|
||||
|
||||
@Injectable()
|
||||
export class FixedDepositProductsTemplateResolver implements Resolve<Object> {
|
||||
|
||||
constructor(private productsService: ProductsService) {}
|
||||
|
||||
/**
|
||||
* Returns the fixed deposit products template data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(): Observable<any> {
|
||||
return this.productsService.getFixedDepositProductsTemplate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="container m-b-20" fxLayout="row" fxLayoutAlign="end" fxLayoutGap="20px">
|
||||
<button mat-raised-button color="primary">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
Create Fixed Deposit Product
|
||||
</button>
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ManageTaxConfigurationsComponent } from './manage-tax-configurations/ma
|
||||
import { RecurringDepositProductsComponent } from './recurring-deposit-products/recurring-deposit-products.component';
|
||||
import { ChargesComponent } from './charges/charges.component';
|
||||
import { FixedDepositProductsComponent } from './fixed-deposit-products/fixed-deposit-products.component';
|
||||
import { CreateFixedDepositProductComponent } from './fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component';
|
||||
import { ProductsMixComponent } from './products-mix/products-mix.component';
|
||||
import { ManageTaxComponentsComponent } from './manage-tax-components/manage-tax-components.component';
|
||||
|
||||
@@ -45,6 +46,7 @@ import { ShareProductAndTemplateResolver } from './share-products/edit-share-pro
|
||||
import { RecurringDepositProductsResolver } from './recurring-deposit-products/recurring-deposit-products.resolver';
|
||||
import { ChargesResolver } from './charges/charges.resolver';
|
||||
import { FixedDepositProductsResolver } from './fixed-deposit-products/fixed-deposit-products.resolver';
|
||||
import { FixedDepositProductsTemplateResolver } from './fixed-deposit-products/fixed-deposit-products-template.resolver';
|
||||
import { ProductsMixResolver } from './products-mix/products-mix.resolver';
|
||||
import { ManageTaxComponentsResolver } from './manage-tax-components/manage-tax-components.resolver';
|
||||
|
||||
@@ -221,11 +223,24 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'fixed-deposit-products',
|
||||
component: FixedDepositProductsComponent,
|
||||
resolve: {
|
||||
fixedDepositProducts: FixedDepositProductsResolver
|
||||
},
|
||||
data: { title: extract('Fixed Deposit Products'), breadcrumb: 'Fixed Deposit Products' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: FixedDepositProductsComponent,
|
||||
resolve: {
|
||||
fixedDepositProducts: FixedDepositProductsResolver
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: CreateFixedDepositProductComponent,
|
||||
data: { title: extract('Create Fixed Deposit Product'), breadcrumb: 'Create' },
|
||||
resolve: {
|
||||
fixedDepositProductsTemplate: FixedDepositProductsTemplateResolver
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'products-mix',
|
||||
@@ -264,6 +279,7 @@ const routes: Routes = [
|
||||
RecurringDepositProductsResolver,
|
||||
ChargesResolver,
|
||||
FixedDepositProductsResolver,
|
||||
FixedDepositProductsTemplateResolver,
|
||||
ProductsMixResolver,
|
||||
ManageTaxComponentsResolver
|
||||
]
|
||||
|
||||
@@ -49,6 +49,16 @@ import { ShareProductPreviewStepComponent } from './share-products/share-product
|
||||
import { CreateShareProductComponent } from './share-products/create-share-product/create-share-product.component';
|
||||
import { ViewShareProductComponent } from './share-products/view-share-product/view-share-product.component';
|
||||
import { EditShareProductComponent } from './share-products/edit-share-product/edit-share-product.component';
|
||||
import { CreateFixedDepositProductComponent } from './fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component';
|
||||
import { FixedDepositProductDetailsStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component';
|
||||
import { FixedDepositProductCurrencyStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component';
|
||||
import { FixedDepositProductTermsStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component';
|
||||
import { FixedDepositProductSettingsStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component';
|
||||
import { FixedDepositProductInterestRateChartStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component';
|
||||
import { FixedDepositProductChargesStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component';
|
||||
import { FixedDepositProductAccountingStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component';
|
||||
import { FixedDepositProductPreviewStepComponent } from './fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component';
|
||||
import { DepositProductIncentiveFormDialogComponent } from './deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component';
|
||||
|
||||
/**
|
||||
* Products Module
|
||||
@@ -102,9 +112,20 @@ import { EditShareProductComponent } from './share-products/edit-share-product/e
|
||||
ShareProductPreviewStepComponent,
|
||||
CreateShareProductComponent,
|
||||
ViewShareProductComponent,
|
||||
EditShareProductComponent
|
||||
EditShareProductComponent,
|
||||
CreateFixedDepositProductComponent,
|
||||
FixedDepositProductDetailsStepComponent,
|
||||
FixedDepositProductCurrencyStepComponent,
|
||||
FixedDepositProductTermsStepComponent,
|
||||
FixedDepositProductSettingsStepComponent,
|
||||
FixedDepositProductInterestRateChartStepComponent,
|
||||
FixedDepositProductChargesStepComponent,
|
||||
FixedDepositProductAccountingStepComponent,
|
||||
FixedDepositProductPreviewStepComponent,
|
||||
DepositProductIncentiveFormDialogComponent
|
||||
],
|
||||
entryComponents: [
|
||||
DepositProductIncentiveFormDialogComponent
|
||||
],
|
||||
providers: [DatePipe]
|
||||
})
|
||||
|
||||
@@ -111,6 +111,14 @@ export class ProductsService {
|
||||
return this.http.get('/fixeddepositproducts');
|
||||
}
|
||||
|
||||
createFixedDepositProduct(fixedDepositProduct: string): Observable<any> {
|
||||
return this.http.post('/fixeddepositproducts', fixedDepositProduct);
|
||||
}
|
||||
|
||||
getFixedDepositProductsTemplate(): Observable<any> {
|
||||
return this.http.get('/fixeddepositproducts/template');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Observable<any>} Tax Components data
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ export class FormfieldBase {
|
||||
this.controlType = options.controlType || '';
|
||||
this.controlName = options.controlName || '';
|
||||
this.label = options.label || '';
|
||||
this.value = options.value || '';
|
||||
this.value = options.value === undefined ? '' : options.value;
|
||||
this.required = !!options.required;
|
||||
this.order = options.order === undefined ? 1 : options.order;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user