/**
  @file getdynamiccolvals.sas
  @brief Provide dynamic list of values according to a SAS program or service
  @details Configuration is made in the MPE_VALIDATIONS table, the dropdown
  can be either a SOFTSELECT_HOOK or HARDSELECT_HOOK.

  Results are sent in ARRAY format for efficiency.

  <h4> Service Inputs </h4>
  <h5> SASCONTROLTABLE </h5>

  |LIBDS:$41.|VARIABLE_NM:$32.|
  |---|---|
  |DC258467.MPE_SECURITY|SAS_GROUP|

  <h5> SOURCE_ROW </h5>

  This contains the raw values from the source table.

  <h4> Service Outputs </h4>


  <h5>DYNAMIC_VALUES</h5>
  The RAW_VALUE column may be charactor or numeric.  If DISPLAY_INDEX is not
  provided, it is added automatically.

  |DISPLAY_INDEX:best.|RAW_VALUE|
  |---|---|
  |1|77.43|
  |2|88.43|

  <h5>DYNAMIC_EXTENDED_VALUES</h5>
  This table is optional.  If provided, it will map the DISPLAY_INDEX from the
  DYNAMIC_VALUES table to additional column/value pairs, that will be used to
  populate dropdowns for _other_ cells in the _same_ row.

  Should be used sparingly!  The use of large tables here can slow down the
  browser.

  |DISPLAY_INDEX:best.|EXTRA_COL_NAME:$32.|DISPLAY_TYPE:$1.|RAW_VALUE_NUM|RAW_VALUE_CHAR:$5000|
  |---|---|---|
  |1|DISCOUNT_RT|N|0.5||
  |1|DISCOUNT_RT|N|0.4||
  |1|DISCOUNT_RT|N|0.3||
  |1|CURRENCY_SYMBOL|C||"GBP"|
  |1|CURRENCY_SYMBOL|C||"RSD"|
  |2|DISCOUNT_RT|N|0.5||
  |2|DISCOUNT_RT|N|0.4||
  |2|CURRENCY_SYMBOL|C||"EUR"|
  |2|CURRENCY_SYMBOL|C||"HKD"|


  <h4> SAS Macros </h4>
  @li dc_assignlib.sas
  @li dc_getservicecode.sas
  @li mf_nobs.sas
  @li mp_abort.sas
  @li mp_include.sas
  @li mp_validatecol.sas
  @li mf_getapploc.sas


  @version 9.3
  @author 4GL Apps Ltd
  @copyright 4GL Apps Ltd.  This code may only be used within Data Controller
    and may not be re-distributed or re-sold without the express permission of
    4GL Apps Ltd.

**/

%mpeinit()

/**
  * Validate inputs
  */
%let err_msg=;
data work.intest;
  set work.SASCONTROLTABLE;

  /* validate libds */
  %mp_validatecol(LIBDS,LIBDS,is_libds)

  /* validate varname */
  is_name=nvalid(variable_nm,'v7');
  putlog (_all_)(=);
  if is_libds ne 1 then do;
    msg='ERR'!!'OR: Invalid libds:'!!libds;
    call symputx('err_msg',msg);
    stop;
  end;
  else if is_name ne 1 then do;
    msg='ERR'!!'OR: Invalid name:'!!variable_nm;
    call symputx('err_msg',msg);
    stop;
  end;
  else do;
    call symputx('variable_nm',variable_nm);
    call symputx('libds',libds);
  end;
  output;
  stop;
run;
%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program..sas
  ,msg=%str(syscc=&syscc after reading work.sascontroltable)
)
%mp_abort(iftrue= (%mf_nobs(work.intest)=0)
  ,mac=&_program
  ,msg=%str(&err_msg)
)

%dc_assignlib(READ,%scan(&libds,1,.))

/* ensure that work.dynamic_extended_values exists  */
data work.dynamic_extended_values;
run;

/**
  * Get the code to execute
  */
data work.codetest;
  set &mpelib..MPE_VALIDATIONS;
  where &dc_dttmtfmt. lt tx_to
    and base_lib="%scan(&libds,1,.)"
    and base_ds="%scan(&libds,2,.)"
    and base_col="&variable_nm"
    and RULE_TYPE in ('HARDSELECT_HOOK','SOFTSELECT_HOOK')
    and RULE_ACTIVE=1;
  putlog (_all_)(=);
  if length(rule_value)>1 then do;
    call symputx('pgmloc',rule_value);
    if scan(upcase(rule_value),-1,'.')='SAS' then do;
      call symputx('pgmtype','PGM');
      call symputx('pgmloc',rule_value);
    end;
    else do;
      apploc="%mf_getapploc()";
      if substr(rule_value,1,1) ne '/'
      then rule_value=cats(apploc,'/',rule_value);
      call symputx('pgmloc',rule_value);
      call symputx('pgmtype','JOB');
    end;
    output;
    stop;
  end;
  else stop;
run;
%mp_abort(iftrue= (%mf_nobs(work.codetest)=0)
  ,mac=&_program
  ,msg=%str(Hook not found in &mpelib..mpe_validations for &libds..&variable_nm)
)

%macro getdynamiccolvals();
%if &pgmtype=PGM %then %do;
  filename sascode "&pgmloc";
%end;
%else %do;
  %dc_getservicecode(loc=&pgmloc
    ,outref=sascode
  )
%end;

%mend getdynamiccolvals;
%getdynamiccolvals()

/* execute the dynamic code */
%mp_include(sascode)
%mp_abort(mode=INCLUDE)

/* ensure that the DISPLAY_INDEX variable exists. */
data work.dynamic_values;
  length DISPLAY_INDEX 8;
  if _n_=1 then call missing(of _all_);
  set work.dynamic_values;
  display_index=coalesce(display_index,_n_);
  keep DISPLAY_INDEX RAW_VALUE;
run;

/* ensure that work.dynamic_extended_values exists with correct types.*/
data work.dynamic_extended_values;
  length DISPLAY_INDEX 8 EXTRA_COL_NAME $32 DISPLAY_TYPE $1
    RAW_VALUE_NUM 8 RAW_VALUE_CHAR $5000 FORCED_VALUE 8;
  if _n_=1 then call missing(of _all_);
  set work.dynamic_extended_values;
run;

%webout(OPEN)
%webout(OBJ,dynamic_values,fmt=N)
%webout(OBJ,dynamic_extended_values,fmt=N)
%webout(CLOSE)

%mpeterm()
