From be7d006e04b4c8575a531b9202be1da004e4689b Mon Sep 17 00:00:00 2001 From: Abhay Chawla Date: Sun, 25 Aug 2019 21:02:53 +0530 Subject: [PATCH] feat: add create fixed deposit product component (#471) - Add fixed deposit product stepper components - Add fixed deposit product component Fixes: #192 --- src/app/pipes/find.pipe.ts | 5 +- ...oduct-incentive-form-dialog.component.html | 67 +++ ...oduct-incentive-form-dialog.component.scss | 0 ...ct-incentive-form-dialog.component.spec.ts | 25 + ...product-incentive-form-dialog.component.ts | 82 ++++ ...reate-fixed-deposit-product.component.html | 107 ++++ ...reate-fixed-deposit-product.component.scss | 0 ...te-fixed-deposit-product.component.spec.ts | 25 + .../create-fixed-deposit-product.component.ts | 104 ++++ ...sit-product-accounting-step.component.html | 253 ++++++++++ ...sit-product-accounting-step.component.scss | 23 + ...-product-accounting-step.component.spec.ts | 25 + ...posit-product-accounting-step.component.ts | 218 +++++++++ ...eposit-product-charges-step.component.html | 74 +++ ...eposit-product-charges-step.component.scss | 11 + ...sit-product-charges-step.component.spec.ts | 25 + ...-deposit-product-charges-step.component.ts | 56 +++ ...posit-product-currency-step.component.html | 46 ++ ...posit-product-currency-step.component.scss | 3 + ...it-product-currency-step.component.spec.ts | 25 + ...deposit-product-currency-step.component.ts | 42 ++ ...eposit-product-details-step.component.html | 39 ++ ...eposit-product-details-step.component.scss | 3 + ...sit-product-details-step.component.spec.ts | 25 + ...-deposit-product-details-step.component.ts | 32 ++ ...ct-interest-rate-chart-step.component.html | 225 +++++++++ ...ct-interest-rate-chart-step.component.scss | 47 ++ ...interest-rate-chart-step.component.spec.ts | 25 + ...duct-interest-rate-chart-step.component.ts | 241 +++++++++ ...eposit-product-preview-step.component.html | 460 ++++++++++++++++++ ...eposit-product-preview-step.component.scss | 45 ++ ...sit-product-preview-step.component.spec.ts | 25 + ...-deposit-product-preview-step.component.ts | 37 ++ ...posit-product-settings-step.component.html | 128 +++++ ...posit-product-settings-step.component.scss | 20 + ...it-product-settings-step.component.spec.ts | 25 + ...deposit-product-settings-step.component.ts | 70 +++ ...-deposit-product-terms-step.component.html | 88 ++++ ...-deposit-product-terms-step.component.scss | 12 + ...posit-product-terms-step.component.spec.ts | 25 + ...ed-deposit-product-terms-step.component.ts | 60 +++ ...ixed-deposit-products-template.resolver.ts | 24 + .../fixed-deposit-products.component.html | 2 +- src/app/products/products-routing.module.ts | 24 +- src/app/products/products.module.ts | 23 +- src/app/products/products.service.ts | 8 + .../formfield/model/formfield-base.ts | 2 +- 47 files changed, 2923 insertions(+), 8 deletions(-) create mode 100644 src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.html create mode 100644 src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.scss create mode 100644 src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.spec.ts create mode 100644 src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts create mode 100644 src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.html create mode 100644 src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.scss create mode 100644 src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.html create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.scss create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.spec.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts create mode 100644 src/app/products/fixed-deposit-products/fixed-deposit-products-template.resolver.ts diff --git a/src/app/pipes/find.pipe.ts b/src/app/pipes/find.pipe.ts index 8d32e0eea..0ce122c3c 100644 --- a/src/app/pipes/find.pipe.ts +++ b/src/app/pipes/find.pipe.ts @@ -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] : ''; } diff --git a/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.html b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.html new file mode 100644 index 000000000..e5cbfb637 --- /dev/null +++ b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.html @@ -0,0 +1,67 @@ +

{{ title }}

+ +
+ + + Attribute + + + {{ attributeName.value }} + + + + Attribute is required + + + + + Condition + + + {{ conditionType.value }} + + + + Condition is required + + + + + Value + + + {{ attributeValue.name }} + + + + + Value is required + + + + + Type + + + {{ incentiveType.value }} + + + + Type is required + + + + + Interest + + + Interest is required + + + +
+ + + + + diff --git a/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.scss b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.spec.ts b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.spec.ts new file mode 100644 index 000000000..5919a0925 --- /dev/null +++ b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DepositProductIncentiveFormDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DepositProductIncentiveFormDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts new file mode 100644 index 000000000..dc499c580 --- /dev/null +++ b/src/app/products/deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component.ts @@ -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, + @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] + }); + } + +} diff --git a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.html b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.html new file mode 100644 index 000000000..4e2be0b08 --- /dev/null +++ b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.html @@ -0,0 +1,107 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + DETAILS + + + + + + + + CURRENCY + + + + + + + + TERMS + + + + + + + + SETTINGS + + + + + + + + INTEREST RATE CHART + + + + + + + + CHARGES + + + + + + + + + ACCOUNTING + + + + + + + + + PREVIEW + + + + + + + + +
diff --git a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.scss b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.spec.ts b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.spec.ts new file mode 100644 index 000000000..c67397c8e --- /dev/null +++ b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateFixedDepositProductComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateFixedDepositProductComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts new file mode 100644 index 000000000..c58107d29 --- /dev/null +++ b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts @@ -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 }); + }); + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html new file mode 100644 index 000000000..41800303b --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html @@ -0,0 +1,253 @@ +
+ +
+ + + + {{ accountingRule }} + + + + + +
+ +

Assets

+ + + Saving reference + + + {{ assetAccount.name }} + + + + Saving reference is required + + + + + +

Liabilities

+ + + Saving control + + + {{ liabilityAccount.name }} + + + + Saving control is required + + + + + Savings transfers in suspense + + + {{ liabilityAccount.name }} + + + + Savings transfers in suspense is required + + + + + +

Expenses

+ + + Interest on savings + + + {{ expenseAccount.name }} + + + + Interest on savings is required + + + + + +

Income

+ + + Income from fees + + + {{ incomeAccount.name }} + + + + Income from fees Repayments is required + + + + + Income from penalties + + + {{ incomeAccount.name }} + + + + Income from penalties is required + + + + + +

Advanced Accounting Rules

+ + + +
+ +

Configure Fund Sources for Payment Channels

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentTypeId | find:paymentTypeData:'id':'name' }} + Fund Source + {{ paymentFundSource.fundSourceAccountId | find:assetAccountData:'id':'name' }} + Actions + + +
+ +

Map Fees to Specific Income Accounts

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.chargeId | find:chargeData:'id':'name' }} + Income Account + {{ feesIncome.incomeAccountId | find:incomeAccountData:'id':'name' }} + Actions + + +
+ +

Map Penalties to Specific Income Accounts

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
Penalty + {{ penaltyIncome.chargeId | find:penaltyData:'id':'name' }} + Income Account + {{ penaltyIncome.incomeAccountId | find:incomeAccountData:'id':'name' }} + Actions + + +
+ +
+ +
+ +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.scss new file mode 100644 index 000000000..e9e5641d0 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.scss @@ -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; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.spec.ts new file mode 100644 index 000000000..043c298eb --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductAccountingStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductAccountingStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts new file mode 100644 index 000000000..9191ee879 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.html new file mode 100644 index 000000000..4a0d5881e --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.html @@ -0,0 +1,74 @@ +
+ + + Charge + + + {{ charge.name }} + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name + {{ charge.name + ', ' + charge.currency.displaySymbol }} + Type + {{ charge.chargeCalculationType.value }} + Amount + {{ charge.amount }} + Collected On + {{ charge.chargeTimeType.value }} + Actions + +
+ +
+ +
+ + +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.scss new file mode 100644 index 000000000..dd420676a --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.scss @@ -0,0 +1,11 @@ +table { + width: 100%; +} + +.mat-elevation-z1 { + margin: 1em 0 1.5em 0; +} + +.margin-t { + margin-top: 1em; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.spec.ts new file mode 100644 index 000000000..c255d7a5c --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductChargesStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductChargesStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts new file mode 100644 index 000000000..799084621 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-charges-step/fixed-deposit-product-charges-step.component.ts @@ -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 + }; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.html new file mode 100644 index 000000000..928030ad7 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.html @@ -0,0 +1,46 @@ +
+ +
+ + + Currency + + + {{ currency.name }} + + + + Currency is required + + + + + Decimal Places + + + Decimal Places is required + + + + + Currency in multiples of + + + Currency in multiples of is required + + + +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.scss new file mode 100644 index 000000000..aa8d23226 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.scss @@ -0,0 +1,3 @@ +.margin-t { + margin-top: 1em; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.spec.ts new file mode 100644 index 000000000..c652db487 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductCurrencyStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductCurrencyStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts new file mode 100644 index 000000000..37a121c59 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-currency-step/fixed-deposit-product-currency-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.html new file mode 100644 index 000000000..8d051e415 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.html @@ -0,0 +1,39 @@ +
+ +
+ + + Product Name + + + Product Name is required + + + + + Short Name + + + Short Name is required + + + + + Description + + + +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.scss new file mode 100644 index 000000000..aa8d23226 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.scss @@ -0,0 +1,3 @@ +.margin-t { + margin-top: 1em; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.spec.ts new file mode 100644 index 000000000..2ccd0b025 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductDetailsStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductDetailsStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts new file mode 100644 index 000000000..3d903b8a5 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-details-step/fixed-deposit-product-details-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.html new file mode 100644 index 000000000..090ffd4b4 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.html @@ -0,0 +1,225 @@ +
+ +
+ +

Interest Rate Charts

+ +
+ +
+ +
+ + + +
+ +
+ +
+ + + Name + + + + + Valid from Date + + + + + Valid from Date is required + + + + + End Date + + + + + + + Description + + + +
+ + Is primary grouping by amount? + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Period + {{ chartSlab.fromPeriod + ' - ' + chartSlab.toPeriod + ' ' + (chartSlab.periodType | find:periodTypeData:'id':'value') }} + Amount Range + {{ chartSlab.amountRangeFrom + ' - ' + chartSlab.amountRangeTo }} + Interest + {{ chartSlab.annualInterestRate }} + Description + {{ chartSlab.description }} + Actions + + + + + +
+ + + +

+ Incentives +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entity Type + {{ incentive.entityType | find:entityTypeData:'id':'value' }} + Attribute Name + {{ incentive.attributeName | find:attributeNameData:'id':'value' }} + Condition Type + {{ incentive.conditionType | find:conditionTypeData:'id':'value' }} + Attribute Value + {{ incentive.attributeValue | find:genderData:'id':'name' }} + {{ incentive.attributeValue }} + {{ incentive.attributeValue | find:clientTypeData:'id':'name' }} + {{ incentive.attributeValue | find:clientClassificationData:'id':'name' }} + Incentive Type + {{ incentive.incentiveType | find:incentiveTypeData:'id':'value'}} + Interest + {{ incentive.amount }} + Actions + + +
+ +
+
+
+ +
+ +
+ +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.scss new file mode 100644 index 000000000..21b059693 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.scss @@ -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; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.spec.ts new file mode 100644 index 000000000..21f54d656 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductInterestRateChartStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductInterestRateChartStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts new file mode 100644 index 000000000..170435122 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html new file mode 100644 index 000000000..ff86222c0 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html @@ -0,0 +1,460 @@ +
+ +

{{ fixedDepositProduct.name }}

+ + + +

Details

+ + + +
+ Short Name: + {{ fixedDepositProduct.shortName }} +
+ +
+ Description: + {{ fixedDepositProduct.description }} +
+ +

Currency

+ + + +
+ Currency: + {{ fixedDepositProduct.currencyCode | find:fixedDepositProductsTemplate.currencyOptions:'code':'name' }} +
+ +
+ Decimal Places: + {{ fixedDepositProduct.digitsAfterDecimal }} +
+ +
+ Currency in multiples of: + {{ fixedDepositProduct.inMultiplesOf }} +
+ +

Terms

+ + + +
+ Deposit Amount: + {{ fixedDepositProduct.depositAmount + ' (Min: ' + (fixedDepositProduct.minDepositAmount ? fixedDepositProduct.minDepositAmount : fixedDepositProduct.depositAmount) + ', Max: ' + (fixedDepositProduct.maxDepositAmount ? fixedDepositProduct.maxDepositAmount : fixedDepositProduct.depositAmount) + ')' }} +
+ +
+ Interest Compounding Period: + {{ fixedDepositProduct.interestCompoundingPeriodType | find:fixedDepositProductsTemplate.interestCompoundingPeriodTypeOptions:'id':'value' }} +
+ +
+ Interest Posting Period: + {{ fixedDepositProduct.interestPostingPeriodType | find:fixedDepositProductsTemplate.interestPostingPeriodTypeOptions:'id':'value' }} +
+ +
+ Interest Calculated using: + {{ fixedDepositProduct.interestCalculationType | find:fixedDepositProductsTemplate.interestCalculationTypeOptions:'id':'value' }} +
+ +
+ Days in Year: + {{ fixedDepositProduct.interestCalculationDaysInYearType | find:fixedDepositProductsTemplate.interestCalculationDaysInYearTypeOptions:'id':'value' }} +
+ +

Settings

+ + + +
+ Lock-in Period: + {{ fixedDepositProduct.lockinPeriodFrequency + ' ' + (fixedDepositProduct.lockinPeriodFrequencyType | find:fixedDepositProductsTemplate.lockinPeriodFrequencyTypeOptions:'id':'value') }} +
+ +
+ Minimum Deposit Term: + {{ fixedDepositProduct.minDepositTerm + ' ' + (fixedDepositProduct.minDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }} +
+ +
+ And thereafter, in Multiples of: + {{ fixedDepositProduct.inMultiplesOfDepositTerm + ' ' + (fixedDepositProduct.inMultiplesOfDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }} +
+ +
+ Minimum Deposit Term: + {{ fixedDepositProduct.maxDepositTerm + ' ' + (fixedDepositProduct.maxDepositTermTypeId | find:fixedDepositProductsTemplate.periodFrequencyTypeOptions:'id':'value') }} +
+ +
+ Apply Penal Interest (less): + {{ fixedDepositProduct.preClosurePenalApplicable ? 'Yes' : 'No' }} +
+ +
+ Penal Interest (%): + {{ fixedDepositProduct.preClosurePenalInterest + '% (' + (fixedDepositProduct.preClosurePenalInterestOnTypeId | find:fixedDepositProductsTemplate.preClosurePenalInterestOnTypeOptions:'id':'value') + ')' }} +
+ +
+ Withhold Tax is Applicable: + {{ fixedDepositProduct.withHoldTax ? 'Yes' : 'No' }} +
+ +
+ Tax Group: + {{ fixedDepositProduct.taxGroupId | find:fixedDepositProductsTemplate.taxGroupOptions:'id':'name' }} +
+ +
+ +

Interest Rate Charts

+ + + +
+ +
+ Name: + {{ chart.name }} +
+ +
+ Valid from Date: + {{ chart.fromDate | date }} +
+ +
+ End Date: + {{ chart.endDate | date }} +
+ +
+ Description: + {{ chart.description }} +
+ +
+ Primary Grouping by Amount: + {{ fixedDepositProduct.isPrimaryGroupingByAmount ? 'Yes' : 'No' }} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Period + {{ chartSlab.fromPeriod + ' - ' + chartSlab.toPeriod + ' ' + (chartSlab.periodType | find:fixedDepositProductsTemplate.chartTemplate.periodTypes:'id':'value') }} + Amount Range + {{ chartSlab.amountRangeFrom + ' - ' + chartSlab.amountRangeTo }} + Interest + {{ chartSlab.annualInterestRate }} + Description + {{ chartSlab.description }} + Actions + + +
+ + +

+ Incentives +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entity Type + {{ incentive.entityType | find:fixedDepositProductsTemplate.chartTemplate.entityTypeOptions:'id':'value' }} + Attribute Name + {{ incentive.attributeName | find:fixedDepositProductsTemplate.chartTemplate.attributeNameOptions:'id':'value' }} + Condition Type + {{ incentive.conditionType | find:fixedDepositProductsTemplate.chartTemplate.conditionTypeOptions:'id':'value' }} + Attribute Value + {{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.genderOptions:'id':'name' }} + {{ incentive.attributeValue }} + {{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.clientTypeOptions:'id':'name' }} + {{ incentive.attributeValue | find:fixedDepositProductsTemplate.chartTemplate.clientClassificationOptions:'id':'name' }} + Incentive Type + {{ incentive.incentiveType | find:fixedDepositProductsTemplate.chartTemplate.incentiveTypeOptions:'id':'value'}} + Amount + {{ incentive.amount }} +
+ +
+
+
+ + + +
+ +
+ +
+ +

Charges

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name + {{ charge.name + ', ' + charge.currency.displaySymbol }} + Type + {{ charge.chargeCalculationType.value }} + Amount + {{ charge.amount }} + Collected On + {{ charge.chargeTimeType.value }} +
+ +
+ +

Accounting

+ + + +
+ Type: + {{ accountingRuleData[fixedDepositProduct.accountingRule-1] }} +
+ +
+ +

Assets

+ +
+ Saving reference: + {{ fixedDepositProduct.savingsReferenceAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} +
+ +

Liabilities

+ +
+ Saving control: + {{ fixedDepositProduct.savingsControlAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} + Savings transfers in suspense: + {{ fixedDepositProduct.transfersInSuspenseAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} +
+ +

Expenses

+ +
+ Interest on savings: + {{ fixedDepositProduct.interestOnSavingsAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'name' }} +
+ +

Income

+ +
+ Income from fees: + {{ fixedDepositProduct.incomeFromFeeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} + Income from penalties: + {{ fixedDepositProduct.incomeFromPenaltyAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
+ +
+ +

Advanced Accounting Rules

+ + + +
+ +

Fund Sources for Payment Channels

+ + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentTypeId | find:fixedDepositProductsTemplate.paymentTypeOptions:'id':'name' }} + Fund Source + {{ paymentFundSource.fundSourceAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} +
+ +
+ +
+ +

Fees to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.chargeId | find:fixedDepositProductsTemplate.chargeOptions:'id':'name' }} + Income Account + {{ feesIncome.incomeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
+ +
+ +
+ +

Penalties to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Penalty + {{ penaltyIncome.chargeId | find:fixedDepositProductsTemplate.penaltyOptions:'id':'name' }} + Income Account + {{ penaltyIncome.incomeAccountId | find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
+ +
+ +
+ +
+ +
+ +
+ + + +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.scss new file mode 100644 index 000000000..9949c63bb --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.scss @@ -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; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.spec.ts new file mode 100644 index 000000000..713d18343 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductPreviewStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductPreviewStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts new file mode 100644 index 000000000..4699723f8 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts @@ -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() { + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.html new file mode 100644 index 000000000..fa894beb3 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.html @@ -0,0 +1,128 @@ +
+ +
+ +

Lock-in Period

+ + + Frequency + + + + + Type + + + {{ lockinPeriodFrequencyType.value }} + + + + +

Minimum Deposit Term

+ + + Frequency + + + Minimum Deposit Term Frequency is required + + + + + Frequency Type + + + {{ periodFrequencyType.value }} + + + + Minimum Deposit Term Frequency Type is required + + + +

And thereafter, in Multiples of

+ + + Frequency + + + + + Type + + + {{ periodFrequencyType.value }} + + + + +

Maximum Deposit Term

+ + + Frequency + + + + + Type + + + {{ periodFrequencyType.value }} + + + + + + +

For Pre-mature closure

+ + + Apply Penal Interest (less) + + + + Penal Interest (%) + + + + + Period + + + {{ preClosurePenalInterestOnType.value }} + + + + + + + + Is Withhold Tax Applicable? + + + + Tax Group + + + {{ taxGroup.name }} + + + + Tax Group is required + + + +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.scss new file mode 100644 index 000000000..72790f3df --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.scss @@ -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; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.spec.ts new file mode 100644 index 000000000..bb4411bb8 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductSettingsStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductSettingsStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts new file mode 100644 index 000000000..67c4ca212 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-settings-step/fixed-deposit-product-settings-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.html new file mode 100644 index 000000000..dfaaf7dfa --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.html @@ -0,0 +1,88 @@ +
+ +
+ +

Deposit Amount

+ + + Minimum + + + + + Default + + + Default Deposit Amount is required + + + + + Maximum + + + + + + + Interest Compounding Period + + + {{ interestCompoundingPeriodType.value }} + + + + Interest Compounding Period is required + + + + + Interest Posting Period + + + {{ interestPostingPeriodType.value }} + + + + Interest Posting Period is required + + + + + Interest Calculated using + + + {{ interestCalculationType.value }} + + + + Interest Calculated using is required + + + + + Days in Year + + + {{ interestCalculationDaysInYearType.value }} + + + + Days in Year is required + + + +
+ +
+ + +
+ +
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.scss b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.scss new file mode 100644 index 000000000..dae670b43 --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.scss @@ -0,0 +1,12 @@ +h4 { + font-weight: 500; + margin: 1em 0; +} + +mat-divider { + margin: 1em 0 2em 0; +} + +.margin-t { + margin-top: 1em; +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.spec.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.spec.ts new file mode 100644 index 000000000..baf9c2aae --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.spec.ts @@ -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; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FixedDepositProductTermsStepComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FixedDepositProductTermsStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts new file mode 100644 index 000000000..06534ec4c --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-terms-step/fixed-deposit-product-terms-step.component.ts @@ -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; + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-products-template.resolver.ts b/src/app/products/fixed-deposit-products/fixed-deposit-products-template.resolver.ts new file mode 100644 index 000000000..be1332fcc --- /dev/null +++ b/src/app/products/fixed-deposit-products/fixed-deposit-products-template.resolver.ts @@ -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 { + + constructor(private productsService: ProductsService) {} + + /** + * Returns the fixed deposit products template data. + * @returns {Observable} + */ + resolve(): Observable { + return this.productsService.getFixedDepositProductsTemplate(); + } + +} diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-products.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-products.component.html index 863c4fb5a..b39d34ddd 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-products.component.html +++ b/src/app/products/fixed-deposit-products/fixed-deposit-products.component.html @@ -1,5 +1,5 @@
- diff --git a/src/app/products/products-routing.module.ts b/src/app/products/products-routing.module.ts index e28ee2001..a8fb27020 100644 --- a/src/app/products/products-routing.module.ts +++ b/src/app/products/products-routing.module.ts @@ -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 ] diff --git a/src/app/products/products.module.ts b/src/app/products/products.module.ts index 141035817..00467c57f 100644 --- a/src/app/products/products.module.ts +++ b/src/app/products/products.module.ts @@ -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] }) diff --git a/src/app/products/products.service.ts b/src/app/products/products.service.ts index d15558a8f..b0936fc55 100644 --- a/src/app/products/products.service.ts +++ b/src/app/products/products.service.ts @@ -111,6 +111,14 @@ export class ProductsService { return this.http.get('/fixeddepositproducts'); } + createFixedDepositProduct(fixedDepositProduct: string): Observable { + return this.http.post('/fixeddepositproducts', fixedDepositProduct); + } + + getFixedDepositProductsTemplate(): Observable { + return this.http.get('/fixeddepositproducts/template'); + } + /** * @returns {Observable} Tax Components data */ diff --git a/src/app/shared/form-dialog/formfield/model/formfield-base.ts b/src/app/shared/form-dialog/formfield/model/formfield-base.ts index 4046e1ee0..cd6a6dfee 100644 --- a/src/app/shared/form-dialog/formfield/model/formfield-base.ts +++ b/src/app/shared/form-dialog/formfield/model/formfield-base.ts @@ -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; }