diff --git a/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.html b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.html new file mode 100644 index 000000000..2fbf18c73 --- /dev/null +++ b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.html @@ -0,0 +1,100 @@ +
+ + + +
+ + + +
+ + + Floating Rate Name + + + Floating Rate Name is required + + + +
+ Is Base Lending + Rate? +
+ +
+ Active +
+ +
+ +
+ + + +
+ +
+ +

Floating Rate Periods

+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
From Date {{ floatingRatePeriod.fromDate | date : 'dd MMMM yyyy' }} Interest Rate {{ floatingRatePeriod.interestRate }} Is Differential? + + + Actions + + +
+ + + +
+ + + + + + +
+ +
+ +
diff --git a/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.scss b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.scss new file mode 100644 index 000000000..75452f1be --- /dev/null +++ b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.scss @@ -0,0 +1,26 @@ +@media (min-width: 992px) { + + .checkbox-wrapper { + position: relative; + + .checkbox { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + } + } + +} + +// TODO: CONFIGURE THESE CLASSES GLOBALLY +.is-differential { + color: #32cd32; +} + +.not-is-differential { + color: #f44366; +} + +table { + width: 100%; +} diff --git a/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.spec.ts b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.spec.ts new file mode 100644 index 000000000..bd5c7dc5c --- /dev/null +++ b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateFloatingRateComponent } from './create-floating-rate.component'; + +describe('CreateFloatingRateComponent', () => { + let component: CreateFloatingRateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateFloatingRateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateFloatingRateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts new file mode 100644 index 000000000..777b0529c --- /dev/null +++ b/src/app/products/floating-rates/create-floating-rate/create-floating-rate.component.ts @@ -0,0 +1,173 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms'; +import { DatePipe } from '@angular/common'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { ProductsService } from '../../products.service'; + +/** Custom Components */ +import { FloatingRatePeriodDialogComponent } from '../floating-rate-period-dialog/floating-rate-period-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Create Floating Rate Component. + */ +@Component({ + selector: 'mifosx-create-floating-rate', + templateUrl: './create-floating-rate.component.html', + styleUrls: ['./create-floating-rate.component.scss'] +}) +export class CreateFloatingRateComponent implements OnInit { + + /** Floating Rate Period Data. */ + floatingRatePeriodsData: any[] = []; + /** Minimum floating rate period date allowed. */ + minDate = new Date(); + /** Floating Rate Form. */ + floatingRateForm: FormGroup; + /** Columns to be displayed in floating rate periods table. */ + displayedColumns: string[] = ['fromDate', 'interestRate', 'isDifferential', 'actions']; + /** Data source for floating rate periods table. */ + dataSource: MatTableDataSource; + /** Date Format. */ + dateFormat = 'dd MMMM yyyy'; + + /** Paginator for floating rate periods table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for floating rate periods table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * @param {Router} router Router for navigation. + * @param {FormBuilder} formBuilder Form Builder. + * @param {ProductsService} productsService Product Service. + * @param {ActivatedRoute} route Activated Route. + * @param {DatePipe} datePipe Date Pipe. + * @param {MatDialog} dialog Dialog reference. + */ + constructor(private router: Router, + private formBuilder: FormBuilder, + private productsService: ProductsService, + private route: ActivatedRoute, + private datePipe: DatePipe, + private dialog: MatDialog) { } + + /** + * Sets the floating rate periods table. + */ + ngOnInit() { + this.setFloatingRates(); + this.createFloatingRateForm(); + } + + /** + * Creates the floating rate form. + */ + createFloatingRateForm() { + this.floatingRateForm = this.formBuilder.group({ + 'name': ['', Validators.required], + 'isBaseLendingRate': [false], + 'isActive': [false] + }); + } + + /** + * Initializes the data source, paginator and sorter for floating rate periods table. + */ + setFloatingRates() { + this.dataSource = new MatTableDataSource(this.floatingRatePeriodsData); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + /** + * Creates the Floating Rate Periods Form. + * @returns {FormGroup} Floating Rate Period Form. + */ + createFloatingRatePeriodsForm(): FormGroup { + return this.formBuilder.group({ + 'fromDate': ['', Validators.required], + 'interestRate': ['', Validators.required], + 'isDifferentialToBaseLendingRate': [false] + }); + } + + /** + * Adds a new floating rate period. + */ + addFloatingRatePeriod() { + const floatingRatePeriodDialogRef = this.dialog.open(FloatingRatePeriodDialogComponent, { + data: {} + }); + floatingRatePeriodDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.floatingRatePeriodsData.push({ + fromDate: this.datePipe.transform(response.fromDate, this.dateFormat), + interestRate: response.interestRate, + isDifferentialToBaseLendingRate: response.isDifferentialToBaseLendingRate, + locale: 'en', + dateFormat: this.dateFormat + }); + this.dataSource.connect().next(this.floatingRatePeriodsData); + } + }); + } + + /** + * Edits floating rate period. + * @param {any} ratePeriod Floating Rate Period. + */ + editFloatingRatePeriod(ratePeriod: any) { + const editFloatingRatePeriodDialogRef = this.dialog.open(FloatingRatePeriodDialogComponent, { + data: { + fromDate: ratePeriod.fromDate, + interestRate: ratePeriod.interestRate, + isDifferentialToBaseLendingRate: ratePeriod.isDifferentialToBaseLendingRate + } + }); + editFloatingRatePeriodDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.floatingRatePeriodsData[this.floatingRatePeriodsData.indexOf(ratePeriod)] = { + fromDate: this.datePipe.transform(response.fromDate, this.dateFormat), + interestRate: response.interestRate, + isDifferentialToBaseLendingRate: response.isDifferentialToBaseLendingRate, + locale: 'en', + dateFormat: this.dateFormat + }; + this.dataSource.connect().next(this.floatingRatePeriodsData); + } + }); + } + + /** + * Deletes the floating rate period. + * @param {any} ratePeriod Floating Rate Period. + */ + deleteFloatingRatePeriod(ratePeriod: any) { + const deleteFloatingRatePeriodRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `floating rate period with from date as ${ratePeriod.fromDate}` } + }); + deleteFloatingRatePeriodRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.floatingRatePeriodsData.splice(this.floatingRatePeriodsData.indexOf(ratePeriod), 1); + this.dataSource.connect().next(this.floatingRatePeriodsData); + } + }); + } + + /** + * Submits the floating rate form and creates floating rate, + * if successful redirects to view created floating rate. + */ + submit() { + this.floatingRateForm.value.ratePeriods = this.floatingRatePeriodsData; + this.productsService.createFloatingRate(this.floatingRateForm.value) + .subscribe((response: any) => { + this.router.navigate(['../', response.resourceId], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.html b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.html new file mode 100644 index 000000000..bfef87fc6 --- /dev/null +++ b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.html @@ -0,0 +1,105 @@ +
+ + + +
+ + + +
+ + + Floating Rate Name + + + Floating Rate Name is required + + + +
+ + Is Base Lending Rate? + +
+ +
+ + Active + +
+ +
+ +
+ + + +
+ +
+ +

Floating Rate Periods

+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
From Date {{ floatingRatePeriod.fromDate | date : 'dd MMMM yyyy' }} Interest Rate {{ floatingRatePeriod.interestRate }} Is Differential? + + + Actions + + +
+ + + +
+ + + + + + +
+ +
+ +
diff --git a/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.scss b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.scss new file mode 100644 index 000000000..75452f1be --- /dev/null +++ b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.scss @@ -0,0 +1,26 @@ +@media (min-width: 992px) { + + .checkbox-wrapper { + position: relative; + + .checkbox { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + } + } + +} + +// TODO: CONFIGURE THESE CLASSES GLOBALLY +.is-differential { + color: #32cd32; +} + +.not-is-differential { + color: #f44366; +} + +table { + width: 100%; +} diff --git a/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.spec.ts b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.spec.ts new file mode 100644 index 000000000..7c495be63 --- /dev/null +++ b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditFloatingRateComponent } from './edit-floating-rate.component'; + +describe('EditFloatingRateComponent', () => { + let component: EditFloatingRateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EditFloatingRateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditFloatingRateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.ts b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.ts new file mode 100644 index 000000000..869aa8fdb --- /dev/null +++ b/src/app/products/floating-rates/edit-floating-rate/edit-floating-rate.component.ts @@ -0,0 +1,185 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms'; +import { DatePipe } from '@angular/common'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { ProductsService } from '../../products.service'; + +/** Custom Components */ +import { FloatingRatePeriodDialogComponent } from '../floating-rate-period-dialog/floating-rate-period-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Edit Floating Rate Component. + */ +@Component({ + selector: 'mifosx-edit-floating-rate', + templateUrl: './edit-floating-rate.component.html', + styleUrls: ['./edit-floating-rate.component.scss'] +}) +export class EditFloatingRateComponent implements OnInit { + + /** Floating Rate Form. */ + floatingRateForm: FormGroup; + /** Floating Rate Data. */ + floatingRateData: any; + /** Minimum floating rate period date allowed. */ + minDate = new Date(); + /** Form Pristine Status. */ + isFloatingRateFormPristine = true; + /** Columns to be displayed in floating rate periods table. */ + displayedColumns: string[] = ['fromDate', 'interestRate', 'isDifferential', 'actions']; + /** Data source for floating rate periods table. */ + dataSource: MatTableDataSource; + /** Date Format. */ + dateFormat = 'dd MMMM yyyy'; + /** Floating Rate Period Data. */ + floatingRatePeriodsData: any[] = []; + + /** Paginator for floating rate periods table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for floating rate periods table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the floating rate data from `resolve`. + * @param {Router} router Router for navigation. + * @param {FormBuilder} formBuilder Form Builder. + * @param {ProductsService} productsService Product Service. + * @param {ActivatedRoute} route Activated Route. + * @param {DatePipe} datePipe Date Pipe. + * @param {MatDialog} dialog Dialog reference. + */ + constructor(private router: Router, + private formBuilder: FormBuilder, + private productsService: ProductsService, + private route: ActivatedRoute, + private datePipe: DatePipe, + private dialog: MatDialog) { + this.route.data.subscribe((data: { floatingRate: any }) => { + this.floatingRateData = data.floatingRate; + this.floatingRatePeriodsData = data.floatingRate.ratePeriods ? data.floatingRate.ratePeriods : []; + }); + } + + /** + * Sets the floating rate periods table. + */ + ngOnInit() { + this.createFloatingRateForm(); + this.setFloatingRates(); + } + + /** + * Creates and sets the Floating Rate Form. + */ + createFloatingRateForm() { + this.floatingRateForm = this.formBuilder.group({ + 'name': [this.floatingRateData.name, Validators.required], + 'isBaseLendingRate': [this.floatingRateData.isBaseLendingRate], + 'isActive': [this.floatingRateData.isActive] + }); + } + + /** + * Initializes the data source, paginator and sorter for floating rate periods table. + */ + setFloatingRates() { + this.dataSource = new MatTableDataSource(this.floatingRatePeriodsData); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + /** + * Adds a new floating rate period. + */ + addFloatingRatePeriod() { + const floatingRatePeriodDialogRef = this.dialog.open(FloatingRatePeriodDialogComponent, { + data: {} + }); + floatingRatePeriodDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.floatingRatePeriodsData.push({ + fromDate: this.datePipe.transform(response.fromDate, this.dateFormat), + interestRate: response.interestRate, + isDifferentialToBaseLendingRate: response.isDifferentialToBaseLendingRate, + locale: 'en', + dateFormat: this.dateFormat + }); + this.dataSource.connect().next(this.floatingRatePeriodsData); + this.isFloatingRateFormPristine = false; + } + }); + } + + /** + * Edits floating rate period. + * @param {any} ratePeriod Floating Rate Period. + */ + editFloatingRatePeriod(ratePeriod: any) { + const editFloatingRatePeriodDialogRef = this.dialog.open(FloatingRatePeriodDialogComponent, { + data: { + fromDate: ratePeriod.fromDate, + interestRate: ratePeriod.interestRate, + isDifferentialToBaseLendingRate: ratePeriod.isDifferentialToBaseLendingRate + } + }); + editFloatingRatePeriodDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.floatingRatePeriodsData[this.floatingRatePeriodsData.indexOf(ratePeriod)] = { + fromDate: this.datePipe.transform(response.fromDate, this.dateFormat), + interestRate: response.interestRate, + isDifferentialToBaseLendingRate: response.isDifferentialToBaseLendingRate, + locale: 'en', + dateFormat: this.dateFormat + }; + this.dataSource.connect().next(this.floatingRatePeriodsData); + this.isFloatingRateFormPristine = false; + } + }); + } + + /** + * Deletes the floating rate period. + * @param {any} ratePeriod Floating Rate Period. + */ + deleteFloatingRatePeriod(ratePeriod: any) { + const deleteFloatingRatePeriodRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `floating rate period with from date as ${ratePeriod.fromDate}` } + }); + deleteFloatingRatePeriodRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.floatingRatePeriodsData.splice(this.floatingRatePeriodsData.indexOf(ratePeriod), 1); + this.dataSource.connect().next(this.floatingRatePeriodsData); + this.isFloatingRateFormPristine = false; + } + }); + } + + /** + * Submits the floating rate form and creates floating rate, + * if successful redirects to view created floating rate. + */ + submit() { + this.floatingRatePeriodsData.map(floatingRatePeriod => { + floatingRatePeriod.modifiedOn = undefined; + floatingRatePeriod.createdOn = undefined; + floatingRatePeriod.id = undefined; + floatingRatePeriod.modifiedBy = undefined; + floatingRatePeriod.createdBy = undefined; + floatingRatePeriod.isActive = undefined; + floatingRatePeriod.locale = 'en'; + floatingRatePeriod.dateFormat = this.dateFormat; + floatingRatePeriod.fromDate = this.datePipe.transform(floatingRatePeriod.fromDate, this.dateFormat); + }); + this.floatingRateForm.value.ratePeriods = this.floatingRatePeriodsData.length > 0 ? this.floatingRatePeriodsData : undefined; + this.productsService.updateFloatingRate(this.route.snapshot.paramMap.get('id'), this.floatingRateForm.value) + .subscribe((response: any) => { + this.router.navigate(['../../', response.resourceId], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.html b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.html new file mode 100644 index 000000000..17874c039 --- /dev/null +++ b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.html @@ -0,0 +1,41 @@ +

Floating Rate Period

+ + + +
+ +
+ + + From Date + + + + + From Date is required + + + + + Interest Rate + + + Interest Rate is required + + + + + Is Differential? + + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.scss b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.spec.ts b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.spec.ts new file mode 100644 index 000000000..a61cc6209 --- /dev/null +++ b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FloatingRatePeriodDialogComponent } from './floating-rate-period-dialog.component'; + +describe('FloatingRatePeriodDialogComponent', () => { + let component: FloatingRatePeriodDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FloatingRatePeriodDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FloatingRatePeriodDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.ts b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.ts new file mode 100644 index 000000000..95a6040ec --- /dev/null +++ b/src/app/products/floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component.ts @@ -0,0 +1,50 @@ +/** Angular Imports */ +import { Component, OnInit, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +/** + * Floating Rate Period Dialog Component. + */ +@Component({ + selector: 'mifosx-floating-rate-period-dialog', + templateUrl: './floating-rate-period-dialog.component.html', + styleUrls: ['./floating-rate-period-dialog.component.scss'] +}) +export class FloatingRatePeriodDialogComponent implements OnInit { + + /** Floating Rate Period Form. */ + floatingRatePeriodForm: FormGroup; + /** Minimum floating rate period date allowed. */ + minDate = new Date(); + + /** + * @param {MatDialogRef} dialogRef Component reference to dialog. + * @param {FormBuilder} formBuilder Form Builder. + * @param {any} data Provides values for the form (if available). + */ + constructor(public dialogRef: MatDialogRef, + public formBuilder: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any) { + } + + /** + * Creates the floating rate period form. + */ + ngOnInit() { + const rowDisabled: Boolean = this.data ? (new Date(this.data.fromDate) < new Date() ? true : false) : false; + this.floatingRatePeriodForm = this.formBuilder.group({ + 'fromDate': [{ value: this.data ? new Date(this.data.fromDate) : '', disabled: rowDisabled }, Validators.required], + 'interestRate': [{ value: this.data ? this.data.interestRate : '', disabled: rowDisabled }, Validators.required], + 'isDifferentialToBaseLendingRate': [{ value: this.data ? this.data.isDifferentialToBaseLendingRate : false, disabled: rowDisabled }] + }); + } + + /** + * Closes the dialog and returns value of the form. + */ + submit() { + this.dialogRef.close(this.floatingRatePeriodForm.value); + } + +} diff --git a/src/app/products/floating-rates/floating-rate.resolver.ts b/src/app/products/floating-rates/floating-rate.resolver.ts new file mode 100644 index 000000000..7b56ce94d --- /dev/null +++ b/src/app/products/floating-rates/floating-rate.resolver.ts @@ -0,0 +1,31 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { ProductsService } from '../products.service'; + +/** + * Floating Rate data resolver. + */ +@Injectable() +export class FloatingRateResolver implements Resolve { + + /** + * @param {ProductsService} productsService Products service. + */ + constructor(private productsService: ProductsService) {} + + /** + * Returns the floating rate data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const floatingRateId = route.paramMap.get('id'); + return this.productsService.getFloatingRate(floatingRateId); + } + +} diff --git a/src/app/products/floating-rates/floating-rates.component.html b/src/app/products/floating-rates/floating-rates.component.html new file mode 100644 index 000000000..7e11c49e3 --- /dev/null +++ b/src/app/products/floating-rates/floating-rates.component.html @@ -0,0 +1,56 @@ +
+ +
+ +
+ +
+ + Filter + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Name {{ floatingRate.name }} Created By {{ floatingRate.createdBy }} Is base lending rate? + + + Active + + +
+ + + +
+ +
diff --git a/src/app/products/floating-rates/floating-rates.component.scss b/src/app/products/floating-rates/floating-rates.component.scss new file mode 100644 index 000000000..04bfa8081 --- /dev/null +++ b/src/app/products/floating-rates/floating-rates.component.scss @@ -0,0 +1,16 @@ +table { + width: 100%; + + .select-row:hover { + cursor: pointer; + } +} + + // TODO: CONFIGURE THESE CLASSES GLOBALLY +.is-base-lending-rate-or-active { + color: #32cd32; +} + +.not-is-base-lending-rate-or-active { + color: #f44366; +} diff --git a/src/app/products/floating-rates/floating-rates.component.spec.ts b/src/app/products/floating-rates/floating-rates.component.spec.ts new file mode 100644 index 000000000..134e6bb47 --- /dev/null +++ b/src/app/products/floating-rates/floating-rates.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FloatingRatesComponent } from './floating-rates.component'; + +describe('FloatingRatesComponent', () => { + let component: FloatingRatesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FloatingRatesComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FloatingRatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/floating-rates/floating-rates.component.ts b/src/app/products/floating-rates/floating-rates.component.ts new file mode 100644 index 000000000..deb6400c8 --- /dev/null +++ b/src/app/products/floating-rates/floating-rates.component.ts @@ -0,0 +1,62 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; + +/** + * Floating Rates Component. + */ +@Component({ + selector: 'mifosx-floating-rates', + templateUrl: './floating-rates.component.html', + styleUrls: ['./floating-rates.component.scss'] +}) +export class FloatingRatesComponent implements OnInit { + + /** Floating Rates data. */ + floatingRatesData: any; + /** Columns to be displayed in floating rates table. */ + displayedColumns: string[] = ['name', 'createdBy', 'isBaseLendingRate', 'isActive']; + /** Data source for floating rates table. */ + dataSource: MatTableDataSource; + + /** Paginator for floating rates table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for floating rates table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the floating rates data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + */ + constructor(private route: ActivatedRoute) { + this.route.data.subscribe(( data: { floatingrates: any } ) => { + this.floatingRatesData = data.floatingrates; + }); + } + + /** + * Filters data in floating rates table based on passed value. + * @param {string} filterValue Value to filter data. + */ + applyFilter(filterValue: string) { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + /** + * Sets the floating rates table. + */ + ngOnInit() { + this.setFloatingRates(); + } + + /** + * Initializes the data source, paginator and sorter for floating rates table. + */ + setFloatingRates() { + this.dataSource = new MatTableDataSource(this.floatingRatesData); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + +} diff --git a/src/app/products/floating-rates/floating-rates.resolver.ts b/src/app/products/floating-rates/floating-rates.resolver.ts new file mode 100644 index 000000000..c044e84e7 --- /dev/null +++ b/src/app/products/floating-rates/floating-rates.resolver.ts @@ -0,0 +1,30 @@ +/** 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'; + +/** + * Floating Rates data resolver. + */ +@Injectable() +export class FloatingRatesResolver implements Resolve { + + /** + * @param {ProductsService} productsService Products service. + */ + constructor(private productsService: ProductsService) {} + + /** + * Returns the floating rates data. + * @returns {Observable} + */ + resolve(): Observable { + return this.productsService.getFloatingRates(); + } + +} diff --git a/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.html b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.html new file mode 100644 index 000000000..1d72fc6d1 --- /dev/null +++ b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.html @@ -0,0 +1,89 @@ +
+ + + +
+ +
+ + + + + +
+ +
+ Floating Rate Name: +
+ +
+ {{ floatingRateData.name }} +
+ +
+ Is Base Lending Rate: +
+ +
+ {{ floatingRateData.isBaseLendingRate ? 'Yes' : 'No' }} +
+ +
+ Is Active: +
+ +
+ {{ floatingRateData.isActive ? 'Yes' : 'No' }} +
+ +
+ +
+ + + +
+ +

Floating Rate Periods

+ +
+ + + + + + + + + + + + + + + + + + + + + +
From Date {{ floatingRate.fromDate | date : 'dd MMMM yyyy' }} Interest Rate {{ floatingRate.interestRate }} Is Differential? + + +
+ + + +
+ +
+ +
+ +
diff --git a/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.scss b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.scss new file mode 100644 index 000000000..3ab2f8005 --- /dev/null +++ b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.scss @@ -0,0 +1,19 @@ +table { + width: 100%; +} + +// TODO: CONFIGURE THESE CLASSES GLOBALLY +.is-differential { + color: #32cd32; +} + +.not-is-differential { + color: #f44366; +} + +.content { + div { + margin: 1rem 0; + word-wrap: break-word; + } +} diff --git a/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.spec.ts b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.spec.ts new file mode 100644 index 000000000..2436680df --- /dev/null +++ b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewFloatingRateComponent } from './view-floating-rate.component'; + +describe('ViewFloatingRateComponent', () => { + let component: ViewFloatingRateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ViewFloatingRateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewFloatingRateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.ts b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.ts new file mode 100644 index 000000000..46303cea5 --- /dev/null +++ b/src/app/products/floating-rates/view-floating-rate/view-floating-rate.component.ts @@ -0,0 +1,54 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; + +/** + * View Floating Rate Component. + */ +@Component({ + selector: 'mifosx-view-floating-rate', + templateUrl: './view-floating-rate.component.html', + styleUrls: ['./view-floating-rate.component.scss'] +}) +export class ViewFloatingRateComponent implements OnInit { + + /** Floating Rate Data. */ + floatingRateData: any; + /** Columns to be displayed in floating rate periods table. */ + displayedColumns: string[] = ['fromDate', 'interestRate', 'isDifferential']; + /** Data source for floating rate periods table. */ + dataSource: MatTableDataSource; + + /** Paginator for floating rate periods table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for floating rate periods table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the floating rate data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + */ + constructor(private route: ActivatedRoute) { + this.route.data.subscribe(( data: { floatingRate: any } ) => { + this.floatingRateData = data.floatingRate; + }); + } + + /** + * Sets the floating rate periods table. + */ + ngOnInit() { + this.setFloatingRates(); + } + + /** + * Initializes the data source, paginator and sorter for floating rate periods table. + */ + setFloatingRates() { + this.dataSource = new MatTableDataSource(this.floatingRateData.ratePeriods); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + +} diff --git a/src/app/products/products-routing.module.ts b/src/app/products/products-routing.module.ts index f51e4e73f..8e4315845 100644 --- a/src/app/products/products-routing.module.ts +++ b/src/app/products/products-routing.module.ts @@ -29,6 +29,10 @@ import { ViewChargeComponent } from './charges/view-charge/view-charge.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 { FloatingRatesComponent } from './floating-rates/floating-rates.component'; +import { CreateFloatingRateComponent } from './floating-rates/create-floating-rate/create-floating-rate.component'; +import { ViewFloatingRateComponent } from './floating-rates/view-floating-rate/view-floating-rate.component'; +import { EditFloatingRateComponent } from './floating-rates/edit-floating-rate/edit-floating-rate.component'; import { ManageTaxComponentsComponent } from './manage-tax-components/manage-tax-components.component'; import { ManageTaxGroupsComponent } from './manage-tax-groups/manage-tax-groups.component'; import { ViewTaxComponentComponent } from './manage-tax-components/view-tax-component/view-tax-component.component'; @@ -52,6 +56,8 @@ import { ChargeResolver } from './charges/charge.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 { FloatingRatesResolver } from './floating-rates/floating-rates.resolver'; +import { FloatingRateResolver } from './floating-rates/floating-rate.resolver'; import { ManageTaxComponentsResolver } from './manage-tax-components/manage-tax-components.resolver'; import { ManageTaxGroupsResolver } from './manage-tax-groups/manage-tax-groups.resolver'; import { TaxComponentResolver } from './manage-tax-components/tax-component.resolver'; @@ -295,6 +301,45 @@ const routes: Routes = [ }, data: { title: extract('Products Mix'), breadcrumb: 'Products Mix' }, }, + { + path: 'floating-rates', + data: { title: extract('Floating Rates'), breadcrumb: 'Floating Rates' }, + children: [ + { + path: '', + component: FloatingRatesComponent, + resolve: { + floatingrates: FloatingRatesResolver + } + }, + { + path: 'create', + component: CreateFloatingRateComponent, + data: { title: extract('Create Floating Rate'), breadcrumb: 'Create' } + }, + { + path: ':id', + data: { title: extract('View Floating Rate'), routeParamBreadcrumb: 'id' }, + children: [ + { + path: '', + component: ViewFloatingRateComponent, + resolve: { + floatingRate: FloatingRateResolver + } + }, + { + path: 'edit', + component: EditFloatingRateComponent, + data: { title: extract('Edit Floating Rate'), breadcrumb: 'Edit', routeParamBreadcrumb: false }, + resolve: { + floatingRate: FloatingRateResolver + } + } + ] + } + ] + } ] } ]) @@ -329,7 +374,9 @@ const routes: Routes = [ ProductsMixResolver, ManageTaxComponentsResolver, ManageTaxGroupsResolver, - TaxComponentResolver + TaxComponentResolver, + FloatingRateResolver, + FloatingRatesResolver ] }) export class ProductsRoutingModule { } diff --git a/src/app/products/products.component.html b/src/app/products/products.component.html index 30a4637c7..c362cfbb8 100644 --- a/src/app/products/products.component.html +++ b/src/app/products/products.component.html @@ -80,7 +80,7 @@

Define Tax components and Tax groups

- + diff --git a/src/app/products/products.module.ts b/src/app/products/products.module.ts index 92de19214..95bc4c3e7 100644 --- a/src/app/products/products.module.ts +++ b/src/app/products/products.module.ts @@ -62,6 +62,11 @@ import { FixedDepositProductPreviewStepComponent } from './fixed-deposit-product import { DepositProductIncentiveFormDialogComponent } from './deposit-product-incentive-form-dialog/deposit-product-incentive-form-dialog.component'; import { ManageTaxGroupsComponent } from './manage-tax-groups/manage-tax-groups.component'; import { ViewTaxComponentComponent } from './manage-tax-components/view-tax-component/view-tax-component.component'; +import { FloatingRatesComponent } from './floating-rates/floating-rates.component'; +import { CreateFloatingRateComponent } from './floating-rates/create-floating-rate/create-floating-rate.component'; +import { ViewFloatingRateComponent } from './floating-rates/view-floating-rate/view-floating-rate.component'; +import { EditFloatingRateComponent } from './floating-rates/edit-floating-rate/edit-floating-rate.component'; +import { FloatingRatePeriodDialogComponent } from './floating-rates/floating-rate-period-dialog/floating-rate-period-dialog.component'; /** * Products Module @@ -90,7 +95,13 @@ import { ViewTaxComponentComponent } from './manage-tax-components/view-tax-comp ChargesComponent, ViewChargeComponent, FixedDepositProductsComponent, + ManageTaxComponentsComponent, ProductsMixComponent, + FloatingRatesComponent, + CreateFloatingRateComponent, + ViewFloatingRateComponent, + EditFloatingRateComponent, + FloatingRatePeriodDialogComponent, ManageTaxComponentsComponent, ViewLoanProductComponent, EditLoanProductComponent, @@ -131,7 +142,7 @@ import { ViewTaxComponentComponent } from './manage-tax-components/view-tax-comp ViewTaxComponentComponent ], entryComponents: [ - DepositProductIncentiveFormDialogComponent + FloatingRatePeriodDialogComponent ], providers: [DatePipe] }) diff --git a/src/app/products/products.service.ts b/src/app/products/products.service.ts index df7aa1413..be46e0df1 100644 --- a/src/app/products/products.service.ts +++ b/src/app/products/products.service.ts @@ -166,4 +166,36 @@ export class ProductsService { return this.http.get('/loanproducts', { params: httpParams }); } + /** + * @returns {Observable} Floating Rates data. + */ + getFloatingRates(): Observable { + return this.http.get('/floatingrates'); + } + + /** + * @param {any} floatingRate Floating Rate. + * @returns {Observable} + */ + createFloatingRate(floatingRate: any): Observable { + return this.http.post('/floatingrates', floatingRate); + } + + /** + * @param {string} floatingRateId Floating Rate ID. + * @returns {Observable} + */ + getFloatingRate(floatingRateId: string): Observable { + return this.http.get(`/floatingrates/${floatingRateId}`); + } + + /** + * @param {string} floatingRateId Floating Rate ID. + * @param {any} floatingRate Changes in Floating Rate. + * @returns {Observable} + */ + updateFloatingRate(floatingRateId: string, floatingRate: any): Observable { + return this.http.put(`/floatingrates/${floatingRateId}`, floatingRate); + } + }