From bf989152e212758c62282db1823e12850bb44826 Mon Sep 17 00:00:00 2001 From: abhay_1806 Date: Thu, 26 Jul 2018 18:38:56 +0530 Subject: [PATCH] refractor: replace select by autocomplete Replace select by autocomplete fields for search journal entries component filters. --- src/app/accounting/accounting.service.ts | 9 +- .../journal-entry.datasource.ts | 47 +++--- .../search-journal-entry.component.html | 60 +++++--- .../search-journal-entry.component.ts | 138 +++++++++++++----- 4 files changed, 167 insertions(+), 87 deletions(-) diff --git a/src/app/accounting/accounting.service.ts b/src/app/accounting/accounting.service.ts index 09c40f7be..7b7413b13 100644 --- a/src/app/accounting/accounting.service.ts +++ b/src/app/accounting/accounting.service.ts @@ -37,17 +37,14 @@ export class AccountingService { } // filterBy: officeId, glAccountId, manualEntriesOnly, fromDate, toDate, transactionId - getJournalEntries(filterBy: any, orderBy: any, sortBy: any, offset: number, limit: number) { - console.log('Order By:', orderBy); - console.log('Sort By:', sortBy); - console.log('Filter By:', filterBy); + getJournalEntries(filterBy: any, orderBy: string, sortOrder: string, offset: number, limit: number) { let httpParams = new HttpParams() .set('offset', offset.toString()) .set('limit', limit.toString()) - .set('sortBy', sortBy) + .set('sortOrder', sortOrder) .set('orderBy', orderBy); filterBy.forEach(function (filter: any) { - if(filter.value) { + if (filter.value) { httpParams = httpParams.set(filter.type, filter.value); } }); diff --git a/src/app/accounting/search-journal-entry/journal-entry.datasource.ts b/src/app/accounting/search-journal-entry/journal-entry.datasource.ts index 88efd420a..49c26db8e 100644 --- a/src/app/accounting/search-journal-entry/journal-entry.datasource.ts +++ b/src/app/accounting/search-journal-entry/journal-entry.datasource.ts @@ -1,36 +1,35 @@ -import { CollectionViewer, DataSource } from "@angular/cdk/collections"; +import { CollectionViewer, DataSource } from '@angular/cdk/collections'; -import { Observable, BehaviorSubject } from "rxjs"; +import { Observable, BehaviorSubject } from 'rxjs'; -import { AccountingService } from "../accounting.service"; +import { AccountingService } from '../accounting.service'; export class JournalEntriesDataSource implements DataSource { - private journalEntriesSubject = new BehaviorSubject([]); - private recordsSubject = new BehaviorSubject(0); + private journalEntriesSubject = new BehaviorSubject([]); + private recordsSubject = new BehaviorSubject(0); - public records$ = this.recordsSubject.asObservable(); + public records$ = this.recordsSubject.asObservable(); - constructor(private accountingService: AccountingService) { } + constructor(private accountingService: AccountingService) { } - loadJournalEntries(filterBy: any, orderBy = '', sortBy = '', offset = 0, limit = 10) { - this.journalEntriesSubject.next([]); - orderBy = (orderBy === 'debit' || orderBy === 'credit') ? 'amount' : orderBy; - this.accountingService.getJournalEntries(filterBy, orderBy, sortBy, offset, limit) - .subscribe((journalEntries: any) => { - console.log(journalEntries); - this.recordsSubject.next(journalEntries.totalFilteredRecords); - this.journalEntriesSubject.next(journalEntries.pageItems); - }); - } + getJournalEntries(filterBy: any, orderBy: string = '', sortOrder: string = '', offset: number = 0, limit: number = 10) { + this.journalEntriesSubject.next([]); + orderBy = (orderBy === 'debit' || orderBy === 'credit') ? 'amount' : orderBy; + this.accountingService.getJournalEntries(filterBy, orderBy, sortOrder, offset, limit) + .subscribe((journalEntries: any) => { + this.recordsSubject.next(journalEntries.totalFilteredRecords); + this.journalEntriesSubject.next(journalEntries.pageItems); + }); + } - connect(collectionViewer: CollectionViewer): Observable { - return this.journalEntriesSubject.asObservable(); - } + connect(collectionViewer: CollectionViewer): Observable { + return this.journalEntriesSubject.asObservable(); + } - disconnect(collectionViewer: CollectionViewer): void { - this.journalEntriesSubject.complete(); - this.recordsSubject.complete(); - } + disconnect(collectionViewer: CollectionViewer): void { + this.journalEntriesSubject.complete(); + this.recordsSubject.complete(); + } } diff --git a/src/app/accounting/search-journal-entry/search-journal-entry.component.html b/src/app/accounting/search-journal-entry/search-journal-entry.component.html index b635b371a..582747885 100644 --- a/src/app/accounting/search-journal-entry/search-journal-entry.component.html +++ b/src/app/accounting/search-journal-entry/search-journal-entry.component.html @@ -1,92 +1,106 @@ -
+
+ - - - {{ office.name }} - - + + - - - {{ affectedGLEntry.name + ' (' + affectedGLEntry.glCode + ')' }} - - + + - + {{ filter.option }} + + + - + +
+ + + + + {{ office.name }} + + + + + + {{ glAccount.name + ' (' + glAccount.glCode + ')' }} + + + +
- + - + - + - + - + - + - + - + - + - + diff --git a/src/app/accounting/search-journal-entry/search-journal-entry.component.ts b/src/app/accounting/search-journal-entry/search-journal-entry.component.ts index f8a710927..2e48f1463 100644 --- a/src/app/accounting/search-journal-entry/search-journal-entry.component.ts +++ b/src/app/accounting/search-journal-entry/search-journal-entry.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; import { MatPaginator, MatSort } from '@angular/material'; import { FormControl } from '@angular/forms'; import { Router } from '@angular/router'; import { merge } from 'rxjs'; -import { tap} from 'rxjs/operators'; +import { tap, startWith, map, distinctUntilChanged, debounceTime} from 'rxjs/operators'; import { AccountingService } from '../accounting.service'; import { JournalEntriesDataSource } from './journal-entry.datasource'; @@ -14,22 +14,22 @@ import { JournalEntriesDataSource } from './journal-entry.datasource'; templateUrl: './search-journal-entry.component.html', styleUrls: ['./search-journal-entry.component.scss'] }) -export class SearchJournalEntryComponent implements OnInit { +export class SearchJournalEntryComponent implements OnInit, AfterViewInit { - // TODO: Update when date and language are set up throughout the application + // TODO: Update once language and date settings are setup minDate = new Date(2000, 0, 1); maxDate = new Date(); + officeName = new FormControl(); - glAccountCode = new FormControl(); - transactionDateFrom = new FormControl(new Date(2000, 0, 1)); - transactionDateTo = new FormControl(new Date()); - transactionId = new FormControl(); - filter = new FormControl(''); - displayedColumns: string[] = ['id', 'officeName', 'transactionId', 'transactionDate', 'glAccountType', 'createdByUserName', 'glAccountCode', 'glAccountName', 'debit', 'credit']; - dataSource: any; officeData: any; + filteredOfficeData: any; + + glAccount = new FormControl(); glAccountData: any; - filterData = [ + filteredGLAccountData: any; + + filter = new FormControl(''); + entryTypeFilterData = [ { option: 'All', value: '' @@ -43,7 +43,16 @@ export class SearchJournalEntryComponent implements OnInit { value: false // Bug: unable to implement from server side } ]; - filterBy = [ + + transactionDateFrom = new FormControl(new Date(2000, 0, 1)); + transactionDateTo = new FormControl(new Date()); + + transactionId = new FormControl(); + + displayedColumns: string[] = ['id', 'officeName', 'transactionId', 'transactionDate', 'glAccountType', 'createdByUserName', 'glAccountCode', 'glAccountName', 'debit', 'credit']; + dataSource: any; + + filterJournalEntriesBy = [ { type: 'officeId', value: '' @@ -91,7 +100,40 @@ export class SearchJournalEntryComponent implements OnInit { } ngAfterViewInit() { + this.officeName.valueChanges + .pipe( + map(value => value.id ? value.id : ''), + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'officeId'); + }) + ) + .subscribe(); + + this.glAccount.valueChanges + .pipe( + map(value => value.id ? value.id : ''), + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'glAccountId'); + }) + ) + .subscribe(); + + this.transactionId.valueChanges + .pipe( + debounceTime(500), + distinctUntilChanged(), + tap((filterValue) => { + this.applyFilter(filterValue, 'transactionId'); + }) + ) + .subscribe(); + this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); + merge(this.sort.sortChange, this.paginator.page) .pipe( tap(() => this.loadJournalEntriesPage()) @@ -99,39 +141,67 @@ export class SearchJournalEntryComponent implements OnInit { .subscribe(); } - getJournalEntries() { - this.dataSource = new JournalEntriesDataSource(this.accountingService); - this.dataSource.loadJournalEntries(this.filterBy, this.sort.active, this.sort.direction, this.paginator.pageIndex, this.paginator.pageSize); - } - loadJournalEntriesPage() { - if(!this.sort.direction) { + if (!this.sort.direction) { delete this.sort.active; } - this.dataSource.loadJournalEntries(this.filterBy, this.sort.active, this.sort.direction, this.paginator.pageIndex * this.paginator.pageSize, this.paginator.pageSize); + this.dataSource.getJournalEntries(this.filterJournalEntriesBy, this.sort.active, this.sort.direction, this.paginator.pageIndex * this.paginator.pageSize, this.paginator.pageSize); } applyFilter(filterValue: string, property: string) { this.paginator.pageIndex = 0; - let findIndex = this.filterBy.findIndex(filter => filter.type === property); - this.filterBy[findIndex].value = filterValue; + const findIndex = this.filterJournalEntriesBy.findIndex(filter => filter.type === property); + this.filterJournalEntriesBy[findIndex].value = filterValue; this.loadJournalEntriesPage(); } - getOffices() { - this.accountingService.getOffices().subscribe(officeData => { - this.officeData = officeData; - }); - } - - getGlAccounts() { - this.accountingService.getGlAccounts().subscribe(glAccountData => { - this.glAccountData = glAccountData; - }); - } - viewTransaction(journalEntry: any) { this.router.navigate(['/accounting/transactions/view', journalEntry.transactionId]); } + displayOfficeName(office?: any): string | undefined { + return office ? office.name : undefined; + } + + displayGLAccount(glAccount?: any): string | undefined { + return glAccount ? glAccount.name + ' (' + glAccount.glCode + ')' : undefined; + } + + 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) + ); + }); + } + + getGlAccounts() { + this.accountingService.getGlAccounts().subscribe(glAccountData => { + this.glAccountData = glAccountData; + this.filteredGLAccountData = this.glAccount.valueChanges + .pipe( + startWith(''), + map((glAccount: any) => typeof glAccount === 'string' ? glAccount : glAccount.name + ' (' + glAccount.glCode + ')'), + map((glAccount: string) => glAccount ? this.filterGLAccountAutocompleteData(this.glAccountData, glAccount) : this.glAccountData) + ); + }); + } + + private filterOfficeAutocompleteData(officeData: any, officeName: string): any { + return officeData.filter((office: any) => office.name.toLowerCase().includes(officeName.toLowerCase())); + } + + private filterGLAccountAutocompleteData(glAccountData: any, glAccount: string): any { + return glAccountData.filter((option: any) => (option.name + ' (' + option.glCode + ')').toLowerCase().includes(glAccount.toLowerCase())); + } + + getJournalEntries() { + this.dataSource = new JournalEntriesDataSource(this.accountingService); + this.dataSource.getJournalEntries(this.filterJournalEntriesBy, this.sort.active, this.sort.direction, this.paginator.pageIndex * this.paginator.pageSize, this.paginator.pageSize); + } + }
Entry ID {{ transaction.id }} {{ journalEntry.id }} Office {{ transaction.officeName }} {{ journalEntry.officeName }} Transaction ID {{ transaction.transactionId }} {{ journalEntry.transactionId }} Transaction Date {{ transaction.transactionDate }} {{ journalEntry.transactionDate }} Type {{ transaction.glAccountType.value }} {{ journalEntry.glAccountType.value }} Created by {{ transaction.createdByUserName }} {{ journalEntry.createdByUserName }} Account Code {{ transaction.glAccountCode }} {{ journalEntry.glAccountCode }} Account Name {{ transaction.glAccountName }} {{ journalEntry.glAccountName }} Debit {{ (transaction.currency.displaySymbol || transaction.currency.code) + ' ' + transaction.amount }} {{ (journalEntry.currency.displaySymbol || journalEntry.currency.code) + ' ' + journalEntry.amount }} Credit {{ (transaction.currency.displaySymbol || transaction.currency.code) + ' ' + transaction.amount }} {{ (journalEntry.currency.displaySymbol || journalEntry.currency.code) + ' ' + journalEntry.amount }}