/** Angular Imports */ import { Component , OnInit , ViewChild , AfterViewInit } from '@angular/core' ; import { MatPaginator } from '@angular/material/paginator' ; import { MatSort } from '@angular/material/sort' ; import { FormControl } from '@angular/forms' ; import { Router , ActivatedRoute } from '@angular/router' ; /** rxjs Imports */ import { merge } from 'rxjs' ; import { tap , startWith , map , distinctUntilChanged , debounceTime } from 'rxjs/operators' ; /** Custom Services */ import { AccountingService } from '../accounting.service' ; import { SettingsService } from 'app/settings/settings.service' ; /** Custom Data Source */ import { JournalEntriesDataSource } from './journal-entry.datasource' ; /**
 * Search journal entry component.
 */ @ Component ( { selector : 'mifosx-search-journal-entry' , templateUrl : './search-journal-entry.component.html' , styleUrls : [ './search-journal-entry.component.scss' ] } ) export class SearchJournalEntryComponent implements OnInit , AfterViewInit { /** Minimum transaction date allowed. */ minDate = new Date ( 2000 , 0 , 1 ) ; /** Maximum transaction date allowed. */ maxDate = new Date ( ) ; /** Office name filter form control.  */ officeName = new FormControl ( ) ; /** Office data. */ officeData : any ; /** Filtered office data for autocomplete. */ filteredOfficeData : any ; /** Gl Account filter form control. */ glAccount = new FormControl ( ) ; /** Gl Account data. */ glAccountData : any ; /** Filtered gl account data. */ filteredGLAccountData : any ; /** Entry type filter form control. */ entryTypeFilter = new FormControl ( '' ) ; /** Entry type filter data. */ entryTypeFilterData = [ { option : 'All' , value : '' } , { option : 'Manual Entries' , value : true } , { option : 'System Entries' , value : false } ] ; /** Transaction date from form control. */ transactionDateFrom = new FormControl ( new Date ( new Date ( ) . setMonth ( new Date ( ) . getMonth ( ) - 1 ) ) ) ; /** Transaction date to form control. */ transactionDateTo = new FormControl ( new Date ( ) ) ; /** Transaction ID form control. */ transactionId = new FormControl ( ) ; /** Columns to be displayed in journal entries table. */ displayedColumns : string [ ] = [ 'id' , 'officeName' , 'transactionId' , 'transactionDate' , 'glAccountType' , 'createdByUserName' , 'glAccountCode' , 'glAccountName' , 'debit' , 'credit' ] ; /** Data source for journal entries table. */ dataSource : JournalEntriesDataSource ; /** Journal entries filter. */ filterJournalEntriesBy = [ { type : 'officeId' , value : '' } , { type : 'glAccountId' , value : '' } , { type : 'manualEntriesOnly' , value : '' } , { type : 'transactionId' , value : '' } , { type : 'fromDate' , value : this . getDate ( new Date ( new Date ( ) . setMonth ( new Date ( ) . getMonth ( ) - 1 ) ) ) } , { type : 'toDate' , value : this . getDate ( new Date ( ) ) } , { type : 'dateFormat' , value : this . settingsService . dateFormat } , { type : 'locale' , value : this . settingsService . language . code } ] ; /** Paginator for journal entries table. */ @ ViewChild ( MatPaginator , { static : true } ) paginator : MatPaginator ; /** Sorter for journal entries table. */ @ ViewChild ( MatSort , { static : true } ) sort : MatSort ; param { AccountingService } accountingService param { ActivatedRoute } route param { SettingsService } settingsService constructor ( private accountingService , private settingsService , private route ) { this . route . data . subscribe ( ( data ) => { this . officeData = data . offices ; this . glAccountData = data . glAccounts ; } ) ; } /**
     * Sets filtered offices and gl accounts for autocomplete and journal entries table.
     */ ngOnInit ( ) { this . setFilteredOffices ( ) ; this . setFilteredGlAccounts ( ) ; this . getJournalEntries ( ) ; } /**
     * Subscribes to all search filters:
     * Office Name, GL Account, Transaction ID, Transaction Date From, Transaction Date To,
     * sort change and page change.
     */ 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 . transactionDateFrom . valueChanges . pipe ( debounceTime ( 500 ) , distinctUntilChanged ( ) , tap ( ( filterValue ) => { this . applyFilter ( this . getDate ( filterValue ) , 'fromDate' ) ; } ) ) . subscribe ( ) ; this . transactionDateTo . valueChanges . pipe ( debounceTime ( 500 ) , distinctUntilChanged ( ) , tap ( ( filterValue ) => { this . applyFilter ( this . getDate ( filterValue ) , 'toDate' ) ; } ) ) . subscribe ( ) ; this . sort . sortChange . subscribe ( ( ) => this . paginator . pageIndex = 0 ) ; merge ( this . sort . sortChange , this . paginator . page ) . pipe ( tap ( ( ) => this . loadJournalEntriesPage ( ) ) ) . subscribe ( ) ; } /**
     * Loads a page of journal entries.
     */ loadJournalEntriesPage ( ) { if ( ! this . sort . direction ) { delete this . sort . active ; } this . dataSource . getJournalEntries ( this . filterJournalEntriesBy , this . sort . active , this . sort . direction , this . paginator . pageIndex , this . paginator . pageSize ) ; } param { string } filterValue param { string } property applyFilter ( filterValue , property ) { this . paginator . pageIndex = 0 ; const findIndex = this . filterJournalEntriesBy . findIndex ( filter => filter . type === property ) ; this . filterJournalEntriesBy [ findIndex ] . value = filterValue ; this . loadJournalEntriesPage ( ) ; } param { any } office returns { string } displayOfficeName ( office ? ) { return office ? office . name : undefined ; } param { any } glAccount returns { string } displayGLAccount ( glAccount ? ) { return glAccount ? glAccount . name + ' (' + glAccount . glCode + ')' : undefined ; } /**
     * Sets filtered offices for autocomplete.
     */ setFilteredOffices ( ) { this . filteredOfficeData = this . officeName . valueChanges . pipe ( startWith ( '' ) , map ( ( office ) => typeof office === 'string' ? office : office . name ) , map ( ( officeName ) => officeName ? this . filterOfficeAutocompleteData ( officeName ) : this . officeData ) ) ; } /**
     * Sets filtered gl accounts for autocomplete.
     */ setFilteredGlAccounts ( ) { this . filteredGLAccountData = this . glAccount . valueChanges . pipe ( startWith ( '' ) , map ( ( glAccount ) => typeof glAccount === 'string' ? glAccount : glAccount . name + ' (' + glAccount . glCode + ')' ) , map ( ( glAccount ) => glAccount ? this . filterGLAccountAutocompleteData ( glAccount ) : this . glAccountData ) ) ; } param { string } officeName returns { any } private filterOfficeAutocompleteData ( officeName ) { return this . officeData . filter ( ( office ) => office . name . toLowerCase ( ) . includes ( officeName . toLowerCase ( ) ) ) ; } param { string } glAccount returns { any } private filterGLAccountAutocompleteData ( glAccount ) { return this . glAccountData . filter ( ( option ) => ( option . name + ' (' + option . glCode + ')' ) . toLowerCase ( ) . includes ( glAccount . toLowerCase ( ) ) ) ; } /**
     * Initializes the data source for journal entries table and loads the first page.
     */ getJournalEntries ( ) { this . dataSource = new JournalEntriesDataSource ( this . accountingService ) ; this . dataSource . getJournalEntries ( this . filterJournalEntriesBy , this . sort . active , this . sort . direction , this . paginator . pageIndex , this . paginator . pageSize ) ; } param { any } timestamp private getDate ( timestamp ) { let day = timestamp . getDate ( ) ; let month = timestamp . getMonth ( ) + 1 ; const year = timestamp . getFullYear ( ) ; if ( day < 10 ) { day = `0${ day }` ; } if ( month < 10 ) { month = `0${ month }` ; } return `${ year }-${ month }-${ day }` ; } }