/** Angular Imports */ import { Component , OnInit } from '@angular/core' ; import { ActivatedRoute } from '@angular/router' ; import { FormControl , FormGroup , Validators } from '@angular/forms' ; import { DatePipe } from '@angular/common' ; /** Custom Services */ import { ReportsService } from '../reports.service' ; import { SettingsService } from 'app/settings/settings.service' ; /** Custom Models */ import { ReportParameter } from '../common-models/report-parameter.model' ; import { SelectOption } from '../common-models/select-option.model' ; /**
 * Run report component.
 */ @ Component ( { selector : 'mifosx-run-report' , templateUrl : './run-report.component.html' , styleUrls : [ './run-report.component.scss' ] } ) export class RunReportComponent implements OnInit { /** Minimum date allowed. */ minDate = new Date ( 2000 , 0 , 1 ) ; /** Maximum date allowed. */ maxDate = new Date ( ) ; /** Contains report specifications i.e: name, type and id */ report : any = { } ; /** Formatted data post labeling of report parameters fetched from API */ paramData : ReportParameter [ ] = [ ] ; /** Array of all parent parameters */ parentParameters : any [ ] = [ ] ; /** Parameter data to configure pentaho output */ pentahoReportParameters : any [ ] = [ ] ; /** Data to be passed on to component selectors */ dataObject : any ; /** Initializes new form group eportForm */ reportForm = new FormGroup ( { } ) ; /** Static Form control for decimal places in output */ decimalChoice = new FormControl ( ) ; /** Toggles Report form */ isCollapsed = false ; /** Toggles  Table output. */ hideTable = true ; /** Toggles Chart output */ hideChart = true ; /** Toggles Pentaho output */ hidePentaho = true ; param { ActivatedRoute } route param { ReportsService } reportsService param { SettingsService } settingsService param { DatePipe } datePipe constructor ( private route , private reportsService , private settingsService , private datePipe ) { this . report . name = this . route . snapshot . params [ 'name' ] ; this . route . queryParams . subscribe ( ( queryParams ) => { this . report . type = queryParams . type ; this . report . id = queryParams . id ; } ) ; this . route . data . subscribe ( ( data ) => { this . paramData = data . reportParameters ; } ) ; } /**
     * Creates and sets the run report form.
     */ ngOnInit ( ) { this . createRunReportForm ( ) ; } /**
     * Establishes form controls for Report Parameter's name attribute,
     * Fetches dropdown options and builds child dependencies.
     */ createRunReportForm ( ) { this . paramData . forEach ( ( param ) => { if ( ! param . parentParameterName ) { this . reportForm . addControl ( param . name , new FormControl ( '' , Validators . required ) ) ; if ( param . displayType === 'select' ) { this . fetchSelectOptions ( param , param . name ) ; } } else { const parent = this . paramData . find ( ( entry ) => entry . name === param . parentParameterName ) ; parent . childParameters . push ( param ) ; this . updateParentParameters ( parent ) ; } } ) ; if ( this . report . type === 'Pentaho' ) { this . reportForm . addControl ( 'outputType' , new FormControl ( '' ) ) ; this . mapPentahoParams ( ) ; } this . decimalChoice . patchValue ( '0' ) ; this . setChildControls ( ) ; } param { ReportParameter } parent updateParentParameters ( parent ) { const parentNames = this . parentParameters . map ( parameter => parameter . name ) ; if ( ! parentNames . includes ( parent . name ) ) { this . parentParameters . push ( parent ) ; } else { const index = parentNames . indexOf ( parent . name ) ; this . parentParameters [ index ] = parent ; } } /**
     * Maps pentaho specific names to form-control names.
     */ mapPentahoParams ( ) { this . reportsService . getPentahoParams ( this . report . id ) . subscribe ( ( data ) => { data . forEach ( ( entry ) => { const param = this . paramData . find ( ( _entry ) => _entry . name === entry . parameterName ) ; param . pentahoName = `R_${ entry . reportParameterName }` ; } ) ; } ) ; } /**
     * Subscribes to changes in parent parameters value, builds child parameter vis-a-vis parent's value.
     */ setChildControls ( ) { this . parentParameters . forEach ( ( param ) => { this . reportForm . get ( param . name ) . valueChanges . subscribe ( ( option ) => { param . childParameters . forEach ( ( child ) => { if ( child . displayType === 'none' ) { this . reportForm . addControl ( child . name , new FormControl ( child . defaultVal ) ) ; } else { this . reportForm . addControl ( child . name , new FormControl ( '' , Validators . required ) ) ; } if ( child . displayType === 'select' ) { const inputstring = `${ child . name }?${ param . inputName }=${ option . id }` ; this . fetchSelectOptions ( child , inputstring ) ; } } ) ; } ) ; } ) ; } param { ReportParameter } param param { string } inputstring fetchSelectOptions ( param , inputstring ) { this . reportsService . getSelectOptions ( inputstring ) . subscribe ( ( options ) => { param . selectOptions = options ; if ( param . selectAll === 'Y' ) { param . selectOptions . push ( { id : '-1' , name : 'All' } ) ; } } ) ; } param { any } response formatUserResponse ( response ) { const formattedResponse = { } ; let newKey ; for ( const [ key , value ] of Object . entries ( response ) ) { if ( key === 'outputType' ) { formattedResponse [ 'output-type' ] = value ; continue ; } const param = this . paramData . find ( ( _entry ) => _entry . name === key ) ; newKey = this . report . type === 'Pentaho' ? param . pentahoName : param . inputName ; switch ( param . displayType ) { case 'text' : formattedResponse [ newKey ] = value ; break ; case 'select' : formattedResponse [ newKey ] = value [ 'id' ] ; break ; case 'date' : const dateFormat = this . settingsService . dateFormat ; formattedResponse [ newKey ] = this . datePipe . transform ( value , dateFormat ) ; break ; case 'none' : formattedResponse [ newKey ] = value ; break ; } } return formattedResponse ; } /**
     * Core run report functionality.
     */ run ( ) { this . isCollapsed = true ; const userResponse = this . formatUserResponse ( this . reportForm . value ) ; this . dataObject = { formData : userResponse , report : this . report , decimalChoice : this . decimalChoice . value } ; switch ( this . report . type ) { case 'SMS' : case 'Table' : this . hideTable = false ; break ; case 'Chart' : this . hideChart = false ; break ; case 'Pentaho' : this . hidePentaho = false ; break ; } } }