/** Angular Imports */ import { Component , OnChanges , Input , Output , EventEmitter } from '@angular/core' ; import { Validators , FormGroup , FormControl } from '@angular/forms' ; import { DatePipe } from '@angular/common' ; /** Rxjs Imports */ import { distinctUntilChanged } from 'rxjs/operators' ; /** Custom Services */ import { ReportsService } from 'app/reports/reports.service' ; import { SettingsService } from 'app/settings/settings.service' ; /** Custom Models */ import { ReportParameter } from 'app/reports/common-models/report-parameter.model' ; import { SelectOption } from 'app/reports/common-models/select-option.model' ; /**
 * Edit Business Rule Parameters.
 */ @ Component ( { selector : 'mifosx-edit-business-rule-parameters' , templateUrl : './edit-business-rule-parameters.component.html' , styleUrls : [ './edit-business-rule-parameters.component.scss' ] } ) export class EditBusinessRuleParametersComponent implements OnChanges { /** Run Report Parameters Data */ @ Input ( ) paramData : any ; /** SMS Campaign */ @ Input ( ) smsCampaign : any ; /** Template Parameters Event Emitter */ @ Output ( ) templateParameters = new EventEmitter ( ) ; /** Initializes new form group ReportForm */ ReportForm = new FormGroup ( { } ) ; /** Array of all parent parameters */ parentParameters : any [ ] = [ ] ; /** Displayed user choices */ paramValue : any ; /** Minimum Date allowed. */ minDate = new Date ( 2000 , 0 , 1 ) ; /** Maximum Date allowed. */ maxDate = new Date ( ) ; param { ReportsService } reportsService constructor ( private reportsService , private settingsService , private datePipe ) { } ngOnChanges ( ) { if ( this . paramData ) { this . ReportForm = new FormGroup ( { } ) ; this . paramValue = JSON . parse ( this . smsCampaign . paramValue ) ; this . createRunReportForm ( ) ; this . disableFormWhenValid ( ) ; this . getResponseHeaders ( ) ; } } /**
     * 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 ) ) ; const controlValue = this . paramValue [ param . variable ] . toString ( ) ; switch ( param . displayType ) { case 'text' : this . ReportForm . get ( param . name ) . patchValue ( controlValue ) ; break ; case 'select' : this . fetchSelectOptions ( param , param . name ) ; break ; case 'date' : const dateFormat = this . settingsService . dateFormat ; const newControlValue = this . datePipe . transform ( controlValue , dateFormat ) ; this . ReportForm . get ( param . name ) . patchValue ( newControlValue ) ; break ; } } else { const parent = this . paramData . find ( ( entry ) => entry . name === param . parentParameterName ) ; parent . childParameters . push ( param ) ; this . updateParentParameters ( parent ) ; } } ) ; 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 ; } } /**
     * 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' } ) ; } const optionId = this . paramValue [ param . variable ] . toString ( ) ; const option = options . find ( entry => entry . id === optionId ) ; this . ReportForm . controls [ param . name ] . patchValue ( { id : optionId , name : option . name } ) ; } ) ; } param { any } option1 param { any } option2 compareOptions ( option1 , option2 ) { return option1 && option2 && option1 . id === option2 . id ; } /**
     * Disable the Report Form once all values are patched.
     */ disableFormWhenValid ( ) { this . ReportForm . statusChanges . pipe ( distinctUntilChanged ( ) ) . subscribe ( ( status ) => { if ( status === 'VALID' ) { this . ReportForm . disable ( ) ; } } ) ; } param { any } response formatUserResponse ( response , forHeaders ) { const formattedResponse = { } ; let newKey ; for ( const [ key , value ] of Object . entries ( response ) ) { const param = this . paramData . find ( ( _entry ) => _entry . variable === key ) ; newKey = forHeaders ? param . inputName : param . variable ; formattedResponse [ newKey ] = value ; } return formattedResponse ; } /**
     * Gets run report response headers.
     * Emits them via template parameters event emitter.
     * TODO: Replace report object with report name once reports service is refactored.
     */ getResponseHeaders ( ) { const reportName = this . paramValue . reportName ; delete this . paramValue . reportName ; const formattedResponse = this . formatUserResponse ( this . paramValue , true ) ; this . reportsService . getRunReportData ( reportName , formattedResponse ) . subscribe ( ( response ) => { this . templateParameters . emit ( response . columnHeaders ) ; } , ( error ) => { this . templateParameters . emit ( null ) ; this . ReportForm . disable ( ) ; } ) ; } }