diff --git a/src/app/accounting/accounting-routing.module.ts b/src/app/accounting/accounting-routing.module.ts index 17aa132aa..0de73dfca 100644 --- a/src/app/accounting/accounting-routing.module.ts +++ b/src/app/accounting/accounting-routing.module.ts @@ -33,6 +33,7 @@ import { EditRuleComponent } from './accounting-rules/edit-rule/edit-rule.compon import { PeriodicAccrualsComponent } from './periodic-accruals/periodic-accruals.component'; import { ProvisioningEntriesComponent } from './provisioning-entries/provisioning-entries.component'; import { CreateProvisioningEntryComponent } from './provisioning-entries/create-provisioning-entry/create-provisioning-entry.component'; +import { ViewProvisioningEntryComponent } from './provisioning-entries/view-provisioning-entry/view-provisioning-entry.component'; const routes: Routes = [ Route.withShell([ @@ -221,6 +222,11 @@ const routes: Routes = [ path: 'create', component: CreateProvisioningEntryComponent, data: { title: extract('Create Provisioning Entry'), breadcrumb: 'Create' } + }, + { + path: 'view/:id', + component: ViewProvisioningEntryComponent, + data: { title: extract('View Provisioning Entry'), routeParamBreadcrumb: 'id' } } ] } diff --git a/src/app/accounting/accounting.module.ts b/src/app/accounting/accounting.module.ts index 36f3be9d9..28b2e6ea6 100644 --- a/src/app/accounting/accounting.module.ts +++ b/src/app/accounting/accounting.module.ts @@ -31,6 +31,7 @@ import { EditRuleComponent } from './accounting-rules/edit-rule/edit-rule.compon import { PeriodicAccrualsComponent } from './periodic-accruals/periodic-accruals.component'; import { ProvisioningEntriesComponent } from './provisioning-entries/provisioning-entries.component'; import { CreateProvisioningEntryComponent } from './provisioning-entries/create-provisioning-entry/create-provisioning-entry.component'; +import { ViewProvisioningEntryComponent } from './provisioning-entries/view-provisioning-entry/view-provisioning-entry.component'; @NgModule({ imports: [ @@ -66,7 +67,8 @@ import { CreateProvisioningEntryComponent } from './provisioning-entries/create- EditRuleComponent, PeriodicAccrualsComponent, ProvisioningEntriesComponent, - CreateProvisioningEntryComponent + CreateProvisioningEntryComponent, + ViewProvisioningEntryComponent ], entryComponents: [ RevertTransactionComponent, diff --git a/src/app/accounting/accounting.service.ts b/src/app/accounting/accounting.service.ts index 3098c01ae..7bc813362 100644 --- a/src/app/accounting/accounting.service.ts +++ b/src/app/accounting/accounting.service.ts @@ -177,4 +177,21 @@ export class AccountingService { return this.http.post('/provisioningentries', provisioningEntry); } + getProvisioningEntry(provisioningEntryId: string) { + return this.http.get(`/provisioningentries/${provisioningEntryId}`); + } + + getLoanProducts() { + return this.http.get('/loanproducts'); + } + + getProvisioningCategories() { + return this.http.get('/provisioningcategory'); + } + + getProvisioningEntryEntries(entryId: string) { + const httpParams = new HttpParams().set('entryId', entryId); + return this.http.get('/provisioningentries/entries', { params: httpParams }); + } + } diff --git a/src/app/accounting/provisioning-entries/provisioning-entries.component.html b/src/app/accounting/provisioning-entries/provisioning-entries.component.html index 6f80763ea..75fa9eaab 100644 --- a/src/app/accounting/provisioning-entries/provisioning-entries.component.html +++ b/src/app/accounting/provisioning-entries/provisioning-entries.component.html @@ -53,7 +53,7 @@ - + diff --git a/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.html b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.html new file mode 100644 index 000000000..c492cb4a2 --- /dev/null +++ b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.html @@ -0,0 +1,125 @@ +
+ + + + + +
+ +
+ Created By +
+ +
+ {{ provisioningEntry.createdUser }} +
+ +
+ Created On +
+ +
+ {{ provisioningEntry.createdDate }} +
+ +
+ Amount to be Reserved +
+ +
+ {{ provisioningEntry.reservedAmount }} +
+ +
+ +
+ +
+ +
+ + +
+ + + + + + + + + + + + + +
+ + + + + {{ office.name }} + + + + + + {{ loanProduct.name }} + + + + + + {{ provisioningCategory.categoryName }} + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Office Name {{ provisioningEntry.officeName }} Product Name {{ provisioningEntry.productName }} Currency Code {{ provisioningEntry.currencyCode }} Category Name {{ provisioningEntry.categoryName }} Provisioning Amount {{ provisioningEntry.amountreserved }} Liability Account (CR) {{ provisioningEntry.liabilityAccountName }} Expense Account (DR) {{ provisioningEntry.expenseAccountName }}
+ + + +
diff --git a/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.scss b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.scss new file mode 100644 index 000000000..3d435a17d --- /dev/null +++ b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.scss @@ -0,0 +1,14 @@ +table { + width: 100%; +} + +.content { + div { + margin: 1rem 0; + word-wrap: break-word; + } + + .header { + font-weight: 500; + } +} diff --git a/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.spec.ts b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.spec.ts new file mode 100644 index 000000000..e66d437d7 --- /dev/null +++ b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewProvisioningEntryComponent } from './view-provisioning-entry.component'; + +describe('ViewProvisioningEntryComponent', () => { + let component: ViewProvisioningEntryComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ViewProvisioningEntryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewProvisioningEntryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.ts b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.ts new file mode 100644 index 000000000..bc4625b1e --- /dev/null +++ b/src/app/accounting/provisioning-entries/view-provisioning-entry/view-provisioning-entry.component.ts @@ -0,0 +1,162 @@ +import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { FormControl } from '@angular/forms'; +import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material'; + +import { startWith, map, debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; + +import { AccountingService } from '../../accounting.service'; + +@Component({ + selector: 'mifosx-view-provisioning-entry', + templateUrl: './view-provisioning-entry.component.html', + styleUrls: ['./view-provisioning-entry.component.scss'] +}) +export class ViewProvisioningEntryComponent implements OnInit, AfterViewInit { + + provisioningEntryId: string; + provisioningEntry: any; + + displayedColumns: string[] = ['officeName', 'productName', 'currencyCode', 'categoryName', 'amountreserved', 'liabilityAccountName', 'expenseAccountName']; + dataSource: any; + filterValue: any = { officeName: '', productName: '', categoryName: '' }; + + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + + officeName = new FormControl(); + officeData: any; + filteredOfficeData: any + + loanProduct = new FormControl(); + loanProductData: any; + filteredLoanProductData: any; + + provisioningCategory = new FormControl(); + provisioningCategoryData: any; + filteredProvisioningCategoryData: any; + + constructor(private route: ActivatedRoute, + private accountingService: AccountingService) { } + + ngOnInit() { + this.provisioningEntryId = this.route.snapshot.paramMap.get('id'); + this.getProvisioningEntry(); + this.getProvisioningEntryEntries(); + this.getOffices(); + this.getLoanProducts(); + this.getProvisioningCategories(); + } + + ngAfterViewInit() { + this.officeName.valueChanges + .pipe( + map(value => value.toLowerCase()), + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'officeName'); + }) + ) + .subscribe(); + + this.loanProduct.valueChanges + .pipe( + map(value => value.toLowerCase()), + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'productName'); + }) + ) + .subscribe(); + + this.provisioningCategory.valueChanges + .pipe( + map(value => value.toLowerCase()), + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'categoryName'); + }) + ) + .subscribe(); + } + + filterPredicate(data: any, filterValue: any) { + return data.officeName.toLowerCase().indexOf(filterValue['officeName']) != -1 + && data.productName.toLowerCase().indexOf(filterValue['productName']) != -1 + && data.categoryName.toLowerCase().indexOf(filterValue['categoryName']) != -1; + } + + applyFilter(filterValue: string, property: string) { + this.filterValue[property] = filterValue; + this.dataSource.filter = this.filterValue; + } + + getProvisioningEntry() { + this.accountingService.getProvisioningEntry(this.provisioningEntryId) + .subscribe((provisioningEntry: any) => { + this.provisioningEntry = provisioningEntry; + }); + } + + getProvisioningEntryEntries() { + this.accountingService.getProvisioningEntryEntries(this.provisioningEntryId) + .subscribe((provisioningEntryEntries: any) => { + this.dataSource = new MatTableDataSource(provisioningEntryEntries.pageItems); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + this.dataSource.filterPredicate = this.filterPredicate; + }); + } + + getOffices() { + this.accountingService.getOffices().subscribe(officeData => { + this.officeData = officeData; + this.filteredOfficeData = this.officeName.valueChanges + .pipe( + startWith(''), + map((office: any) => typeof office === 'string' ? office : office.name), + map((officeName: string) => officeName ? this.filterOfficeAutocompleteData(this.officeData, officeName) : this.officeData) + ); + }); + } + + getLoanProducts() { + this.accountingService.getLoanProducts().subscribe(loanProductData => { + this.loanProductData = loanProductData; + this.filteredLoanProductData = this.loanProduct.valueChanges + .pipe( + startWith(''), + map((loanProduct: any) => typeof loanProduct === 'string' ? loanProduct : loanProduct.name), + map((loanProductName: string) => loanProductName ? this.filterLoanProductAutocompleteData(this.loanProductData, loanProductName) : this.loanProductData) + ); + }); + } + + getProvisioningCategories() { + this.accountingService.getProvisioningCategories().subscribe(provisioningCategoryData => { + this.provisioningCategoryData = provisioningCategoryData; + this.filteredProvisioningCategoryData = this.provisioningCategory.valueChanges + .pipe( + startWith(''), + map((provisioningCategory: any) => typeof provisioningCategory === 'string' ? provisioningCategory : provisioningCategory.categoryName), + map((provisioningCategoryName: string) => provisioningCategoryName ? this.filterProvisioningCategoryAutocompleteData(this.provisioningCategoryData, provisioningCategoryName) : this.provisioningCategoryData) + ); + }); + } + + private filterOfficeAutocompleteData(officeData: any, officeName: string): any { + return officeData.filter((office: any) => office.name.toLowerCase().includes(officeName.toLowerCase())); + } + + private filterLoanProductAutocompleteData(loanProductData: any, loanProductName: string): any { + return loanProductData.filter((loanProduct: any) => loanProduct.name.toLowerCase().includes(loanProductName.toLocaleLowerCase())); + } + + private filterProvisioningCategoryAutocompleteData(provisioningCategoryData: any, provisioningCategoryName: string): any { + return provisioningCategoryData.filter((provisioningCategory: any) => provisioningCategory.categoryName.toLowerCase().includes(provisioningCategoryName.toLocaleLowerCase())); + } + +}