SAS Documentation
SASĀ® Solution for Stress Testing
Reference manual - version 08.2021
Loading...
Searching...
No Matches
batch_run_sample_cycles.sas
1/* ------------------------------------------------------------------------------------------------- */
2/* REQUIRED INPUTS */
3/* ------------------------------------------------------------------------------------------------- */
4
5/* Description of input parameters:
6 *
7 * RGF_HOST - SAS Risk Governance Framework host
8 * RGF_PORT - SAS Risk Governance Framework port
9 * RGF_SERVER - SAS Risk Governance Framework server (default: SASRiskGovernanceFramework)
10 * RGF_SOLUTION - SAS Risk Governance Framework content id (default: rmc)
11 * RGF_USER - Username (must have necessary RGF access to run through the cycle - e.g. a user with the RGF: Adminsitration role)
12 * RGF_PASSWD - Password for the RGF_USER
13 * SOLUTION_VERSION - version of the solution content (e.g. st.2021.08)
14 * STRATUM_VERSION - version of the Stratum core (e.g. rmc.2021.10 or rmc.* to pick up the latest version of rmc)
15 * SCENARIO_FILE_PATH - path to the scenario files (if loading scenarios via this script)
16 * PERSPECTIVE_ID - perspective id
17 * PARAM_TABLE_PATH - path to the file containing the parameters for batch execution
18 * PARAM_TABLE_NAME - name of the file containing the parameters for batch execution
19 * LOG_LEVEL - Debug logging level (takes values 1-5, 1 being the least amount of logging and 5 being the most, defaults to 1)
20 *
21 * Note: The solution version and stratum version come from the federated area properties registered in SAS Management Console
22 * in the IRM Mid-Tier Server (com.sas.solutions.risk.irm.fa._________)
23 */
24
25%let host = %sysget(RGF_HOST);
26%let port = %sysget(RGF_PORT);
27%let server = %sysfunc(coalescec(%sysget(RGF_SERVER),SASRiskGovernanceFramework));
28%let solution = %sysfunc(coalescec(%sysget(RGF_SOLUTION),rmc));
29%let username = %sysget(RGF_USER);
30%let password = %sysget(RGF_PASSWD);
31%let solution_version = %sysget(SOLUTION_VERSION);
32%let stratum_version = %sysget(STRATUM_VERSION);
33%let scenario_file_path = %sysget(SCENARIO_FILE_PATH);
34%let perspective = %sysget(PERSPECTIVE_ID);
35%let param_table_path = %sysget(PARAM_TABLE_PATH);
36%let param_table_name = %sysget(PARAM_TABLE_NAME);
37%let log_level = %sysfunc(coalescec(%sysget(LOG_LEVEL),1));
38
39/* Print the input parameters for debugging purposes */
40%put &=host;
41%put &=port;
42%put &=server;
43%put &=solution;
44%put &=username;
45%put &=solution_version;
46%put &=stratum_version;
47%put &=scenario_file_path;
48%put &=perspective;
49%put &=param_table_path;
50%put &=param_table_name;
51%put &=log_level;
52
53/* ------------------------------------------------------------------------------------------------- */
54/* Read the parameters file */
55/* ------------------------------------------------------------------------------------------------- */
56
57/* Get the path to the solution content */
58%let fa_path = %sysfunc(metadata_appprop(IRM Mid-Tier Server, com.sas.solutions.risk.irm.fa.&solution_version.));
59%let fa_id = %scan(&fa_path., -1, \/);
60%let source_path = %sysfunc(prxchange(s/([\\\/]&fa_id.)?[\\\/]*$//, 1, &fa_path.));
61
62/* Make sure the stratum_version parameter has been set */
63%if %sysevalf(%superq(stratum_version) =, boolean) %then %do;
64 %let stratum_version = rmc.*;
65%end;
66
67/* Set up the environment */
68%include "&source_path./&fa_id./source/sas/ucmacros/irm_setup.sas";
69%irm_setup(source_path = &source_path.
70 , fa_id = &fa_id.
71 , rmc_fa_id = &stratum_version.
72 );
73
74/* Set logging options (based on the value of LOG_LEVEL macro variable) */
75%irm_set_logging_options();
76
77/* If stratum version is rmc.* then update it to the most recent rmc version in case any new cycles are created */
78%if "&stratum_version." eq "rmc.*" %then %do;
79 /* Get the list of IRM federated areas matching the specified value */
80 %irm_get_swc_property(swc_name = IRM Mid-Tier Server
81 , property = com.sas.solutions.risk.irm.fa.(?!readonly.)&stratum_version.
82 , outvar = swc_property_value
83 , out_ds = irm_federated_areas_rmc
84 , pattern_match_flg = Y
85 );
86 /* Sort in descending order */
87 proc sort data = irm_federated_areas_rmc;
88 by descending property_name;
89 run;
90 /* Get the top-most rmc federated area */
91 data _null_;
92 set irm_federated_areas_rmc (obs=1);
93 call symputx("stratum_version", substr(property_name, index(property_name,".rmc.")+1), "L");
94 run;
95 %put NOTE: Using RMC version &stratum_version. for Cycle data loader.;
96%end;
97
98/* Suppress temporarily the printing options to the log */
99%let oldLogOptions =
100 %sysfunc(getoption(notes))
101 %sysfunc(getoption(symbolgen))
102 %sysfunc(getoption(mprint))
103 %sysfunc(getoption(mlogic))
104;
105option nonotes nosgen nomprint nomlogic;
106
107/* Generate TGT ticket */
108%let rgf_tgt_ticket=;
109%irm_rest_get_ticket(url = &host.:&port.
110 , username = &username.
111 , password = &password.
112 , ticketType = TGT
113 , outVarTicket = rgf_tgt_ticket
114 );
115
116/* Reactivate the log options */
117option &oldLogOptions.;
118
119/* Read in the parameters table */
120%macro read_workflow_table(filePath =, fileName =);
121 /* If param table is an xlsx file */
122 %if %sysfunc(prxmatch(/.*\.xlsx/i, %bquote(&fileName.))) %then %do;
123 libname batch XLSX "&filePath.\&fileName.";
124 data workflow;
125 length A $ 1.;
126 set batch.workflow(where=(substr(cycle, 1, 1) ne '#'));
127 if not missing(cycle);
128 /* Skip commented rows (rows with a # in column A) */
129 if missing(A);
130 drop A;
131 run;
132 data scen_info;
133 length A $ 1.;
134 set batch.scenarios;
135 /* Skip commented rows (rows with a # in column A) */
136 if missing(A);
137 drop A;
138 run;
139 data seg_schemes;
140 length A $ 1.;
141 set batch.seg_schemes;
142 /* Skip commented rows (rows with a # in column A) */
143 if missing(A);
144 drop A;
145 run;
146 data alloc_schemes;
147 length A $ 1.;
148 set batch.alloc_schemes;
149 /* Skip commented rows (rows with a # in column A) */
150 if missing(A);
151 drop A;
152 run;
153 data bus_evolution_plans;
154 length A $ 1.;
155 set batch.bus_evolution_plans;
156 /* Skip commented rows (rows with a # in column A) */
157 if missing(A);
158 drop A;
159 run;
160 data synthInstAllocations;
161 length A $ 1.;
162 set batch.synthInstAllocations;
163 /* Skip commented rows (rows with a # in column A) */
164 if missing(A);
165 drop A;
166 run;
167 /* Check if cycle table exists */
168 proc sql;
169 select count(*) into : cycle_table_exists
170 from dictionary.tables
171 where libname = 'BATCH' and memname = 'CYCLES';
172 quit;
173 %if &cycle_table_exists. %then %do;
174 data create_cycle_info;
175 length A $ 1.;
176 set batch.cycles;
177 /* Skip commented rows (rows with a # in column A) */
178 if missing(A);
179 drop A;
180 run;
181 %end;
182 libname batch clear;
183 %if %sysfunc(exist(workflow)) = 0 %then %do;
184 %put Specified Excel file does not exist in &filePath.;
185 %end;
186 %end;
187 /* If param table is a SAS table */
188 %else %if %sysfunc(prxmatch(/.*\.sas7bdat/i, %bquote(&fileName.))) %then %do;
189 libname batch "&filePath.";
190 data workflow;
191 set batch.%sysfunc(prxchange(s/(.*).sas7bdat$/$1/i, 1, %bquote(&workflow_table_name)))(where=(substr(cycle, 1, 1) ne '#'));
192 if not missing(cycle);
193 run;
194 libname batch clear;
195 %if %sysfunc(exist(workflow)) = 0 %then %do;
196 %put Specified SAS dataset &fileName. does not exist in &filePath.;
197 %end;
198 %end;
199 /* Otherwise, the file extension is not supported - abort */
200 %else %do;
201 %put ERROR: File extension not recognized. File extension must be .xlsx or .sas7bdat;
202 %abort cancel;
203 %end;
204%mend;
205
206/* Read the scenario/cycle information from the parameters file */
207%read_workflow_table(filePath=&param_table_path.
208 , fileName=&param_table_name.);
209
210/* ------------------------------------------------------------------------------------------------- */
211/* Create cycles from the Cycles tab */
212/* ------------------------------------------------------------------------------------------------- */
213
214%macro create_new_cycles();
215 /* Initialize tot_cycles to 0 in case all cycles are commented out */
216 %let tot_cycles = 0;
217 /* Read the cycle information */
218 data _null_;
219 set create_cycle_info end=last;
220 call symputx(cats("cycle_id_", put(_N_, 8.)), cycle_id, "L");
221 call symputx(cats("cycle_name_", put(_N_, 8.)), cycle_name, "L");
222 call symputx(cats("cycle_desc_", put(_N_, 8.)), cycle_description, "L");
223 call symputx(cats("cycle_base_dt_", put(_N_, 8.)), cycle_base_dt, "L");
224 call symputx(cats("entity_id_", put(_N_, 8.)), entity_id, "L");
225 call symputx(cats("initial_run_flg_", put(_N_, 8.)), initial_run_flg, "L");
226 call symputx(cats("workflow_template_id_", put(_N_, 8.)), workflow_template_id, "L");
227 call symputx(cats("dimensional_points_", put(_N_, 8.)), dimensional_points, "L");
228 call symputx(cats("control_framework_id_", put(_N_, 8.)), control_framework_id, "L");
229 call symputx(cats("func_currency_", put(_N_, 8.)), func_currency, "L");
230 call symputx(cats("prev_afs_filter_", put(_N_, 8.)), previous_AFS_results_filter, "L");
231 call symputx(cats("prev_frhtm_filter_", put(_N_, 8.)), previous_FRHTM_results_filter, "L");
232 if last then
233 call symputx("tot_cycles", _N_, "L");
234 run;
235 %do c = 1 %to &tot_cycles.;
236 /* Get the workflow template key from the workflow template id */
237 %let ticket =;
238 %let httpSuccess=;
239 %let responseStatus=;
240 %irm_rest_get_rgf_basic_info( object_uri = workflowTemplates
241 , host = &host.
242 , port = &port.
243 , tgt_ticket = &rgf_tgt_ticket.
244 , filter = filter=eq(objectId,%27&&workflow_template_id_&c..%27)
245 , outds = workflow_template_&c.
246 , outVarTicket = ticket
247 , outSuccess = httpSuccess
248 , outResponseStatus = responseStatus
249 );
250 /* Check for errors */
251 %if &httpSuccess ne 1 or %rsk_attrn(workflow_template_&c., NLOBS) eq 0 %then %do;
252 %put ERROR: Could not find workflow template with id &&workflow_template_id_&c.. when creating cycle &&cycle_name_&c... Execution stopped due to errors.;
253 %abort cancel;
254 %end;
255 /* Get the workflow template key from the workflow template id */
256 data _null_;
257 set workflow_template_&c.;
258 call symputx("workflow_template_key_&c.", key, "L");
259 run;
260 %let objectLinks = %bquote([{"linkTypeId": "wfTemplate_cycle", "businessObject1": &&workflow_template_key_&c..});
261 /* If a control framework was provided, get the key and add the link into to objectLinks */
262 %if ("&&control_framework_id_&c.." ne "" and "&&control_framework_id_&c.." ne ".") %then %do;
263 /* Get the control framework key from the control framework id */
264 %let ticket =;
265 %let httpSuccess=;
266 %let responseStatus=;
267 %irm_rest_get_rgf_basic_info( object_uri = controlFrameworks
268 , host = &host.
269 , port = &port.
270 , tgt_ticket = &rgf_tgt_ticket.
271 , filter = filter=eq(objectId,%27&&control_framework_id_&c..%27)
272 , outds = control_framework_&c.
273 , outVarTicket = ticket
274 , outSuccess = httpSuccess
275 , outResponseStatus = responseStatus
276 );
277 /* Check for errors */
278 %if &httpSuccess ne 1 %then %do;
279 %put ERROR: Could not find control framework with id &&control_framework_id_&c.. when creating cycle &&cycle_name_&c... Execution stopped due to errors.;
280 %abort cancel;
281 %end;
282 /* Get the control framework key from the control framework id */
283 data _null_;
284 set control_framework_&c.;
285 call symputx("control_framework_key_&c.", key, "L");
286 run;
287 %let objectLinks = %bquote(&objectLinks., {"linkTypeId": "cycle_controlFramework", "businessObject2": &&control_framework_key_&c..}]);
288 %end;
289 %else %do;
290 %let objectLinks = %bquote(&objectLinks.]);
291 %end;
292 /* Create the cycle */
293 %let ticket =;
294 %let httpSuccess=;
295 %let responseStatus=;
296 %irm_rest_create_rgf_cycle(host = &host.
297 , server = &server.
298 , solution = &solution.
299 , perspective = %lowcase(&perspective.)
300 , port = &port.
301 , tgt_ticket = &rgf_tgt_ticket.
302 , name = &&cycle_name_&c..
303 , cycleId = &&cycle_id_&c..
304 , description = &&cycle_desc_&c..
305 , versionNm = &solution_version.
306 , baseDt = &&cycle_base_dt_&c..
307 , rmcVersionNm = &stratum_version.
308 , entityId = &&entity_id_&c..
309 %if %sysevalf(%superq(initial_run_flg_&c.) ne,boolean) %then %do;
310 , initialRunFlg = true /* Initial run flag must be true when creating the cycle, otherwise the workflow cannot be linked since there are no prev data links*/
311 %end;
312 , funcCurrency = &&func_currency_&c..
313 , dimensional_points = &&dimensional_points_&c..
314 , objectLinks = &objectLinks.
315 , outds = cycle_info_&c.
316 , outVarTicket = ticket
317 , outSuccess = httpSuccess
318 , outResponseStatus = responseStatus
319 );
320 /* Check for errors */
321 %if &httpSuccess ne 1 %then %do;
322 %put ERROR: Could not create cycle &&cycle_name_&c... Execution stopped due to errors.;
323 %abort cancel;
324 %end;
325 /* Get the cycle key from the created cycle */
326 data _null_;
327 set cycle_info_&c.;
328 call symputx("cycle_key_&c.", key, "L");
329 run;
330 /* If Initial Run Flag is false or no then update the cycle */
331 %if %lowcase(&&initial_run_flg_&c..) eq false or %lowcase(&&initial_run_flg_&c..) eq no %then %do;
332 /* GET ETag for If-Match Header */
333 filename get_resp temp;
334 data _null_;
335 file get_resp;
336 put;
337 run;
338 %let requestUrlCycle_&c. = &host.:&port./&server./rest/&solution./cycles/&&cycle_key_&c..;
339 %let ticket =;
340 %let httpSuccess=;
341 %let responseStatus=;
342 %irm_rest_request(url = &&requestUrlCycle_&c..
343 , method = GET
344 , server = &server.
345 , tgt_ticket = &rgf_tgt_ticket.
346 , headerIn = Accept:application/json
347 , body =
348 , parser = sas.risk.irm.rgf_rest_parser.rmcRestCycle
349 , outds = get_result
350 , headerOut = get_resp
351 , outVarTicket = ticket
352 , outSuccess = httpSuccess
353 , outResponseStatus = responseStatus
354 );
355 %if &httpSuccess ne 1 %then %do;
356 %put Task: &task_name.... Execution stopped due to errors. Bad request on GET to cycle &cycle_key..;
357 %abort cancel;
358 %end;
359 data _null_;
360 length Header $ 50 Value $ 200;
361 infile get_resp dlm=':';
362 input Header $ Value $;
363 if Header = 'ETag';
364 call symputx('etag', Value);
365 run;
366 /* Build the header and body for the patch request */
367 filename headin temp;
368 data _null_;
369 file headin;
370 put 'Accept: application/json';
371 put "If-Match: &etag.";
372 run;
373 filename cycleBdy temp;
374 data _null_;
375 file cycleBdy;
376 put "{""key"": &&cycle_key_&c..";
377 put " , ""changeReason"": ""Batch execution update - set Initial Run Flag to No.""";
378 put " , ""customFields"": {";
379 put " ""initialRunFlg"":false";
380 put " }";
381 put "}";
382 run;
383 %let ticket =;
384 %let httpSuccess=;
385 %let responseStatus=;
386 %irm_rest_request(url = &&requestUrlCycle_&c..;
387 , method = PATCH
388 , server = &server.
389 , tgt_ticket = &rgf_tgt_ticket.
390 , headerIn = headin
391 , body = cycleBdy
392 , parser = sas.risk.irm.rgf_rest_parser.rmcRestCycle
393 , outds = put_result
394 , outVarTicket = ticket
395 , outSuccess = httpSuccess
396 , outResponseStatus = responseStatus
397 );
398 %if &httpSuccess ne 1 %then %do;
399 %put ERROR: PATCH request to update Initial Run Flag failed. Execution stopped due to errors.;
400 %abort cancel;
401 %end;
402 filename cycleBdy clear;
403 filename get_resp clear;
404 filename headin clear;
405 %end;
406 %end;
407%mend;
408
409%if %rsk_dsexist(create_cycle_info) %then %do;
410 %create_new_cycles();
411%end;
412
413/* ------------------------------------------------------------------------------------------------- */
414/* Load the sample Master Risk Scenarios */
415/* ------------------------------------------------------------------------------------------------- */
416
417/* Get the dimensional point rk for the master risk scenarios */
418%let perspective_id = %sysfunc(upcase(&perspective.));
419%let ticket =;
420%let dim_point_key=;
421%irmc_get_dim_point_from_groovy(query_type = emptyLocationWithPerspectiveNodes
422 , perspective_id = &perspective_id.
423 , outVar = dim_point_key
424 , host = &host.
425 , server = &server.
426 , solution = &solution.
427 , port = &port.
428 , tgt_ticket = &rgf_tgt_ticket.
429 , outVarTicket = ticket
430 , outSuccess = httpSuccess
431 , outResponseStatus = responseStatus
432 );
433
434/* Macro to import Risk Scenario Manager scenarios */
435%macro import_rsm_scenarios(scen_info_table=);
436 /* Get the distinct list of files/workgroups/historyDates */
437 proc sql;
438 create table rsm_scen_files as
439 select distinct file_name
440 , workgroup
441 , history_date
442 from &scen_info_table.;
443 quit;
444 /* Get the number of files to process */
445 %let num_scen_files = %rsk_attrn(rsm_scen_files, nlobs);
446 /* Loop through each scenario file and upload it to RSM */
447 %do s = 1 %to &num_scen_files.;
448 /* Get the current scenario info */
449 data _null_;
450 set rsm_scen_files (firstobs = &s. obs=%eval(&s.));
451 call symputx("curr_file_name", file_name, "L");
452 call symputx("curr_workgroup", workgroup, "L");
453 call symputx("curr_history_date", history_date, "L");
454 run;
455 /* Create the scenario in RSM */
456 %let ticket =;
457 %let httpSuccess=;
458 %let responseStatus=;
459 %irm_rest_create_rsm_scenario(host = &host.
460 , server = SASRiskScenarioManager
461 , port = &port.
462 , tgt_ticket = &rgf_tgt_ticket.
463 , historyDate = &curr_history_date.
464 , workGroup = &curr_workgroup.
465 , dirPath = &scenario_file_path.
466 , fileName = &curr_file_name.
467 , outVarTicket = ticket
468 , outSuccess = httpSuccess
469 , outResponseStatus = responseStatus
470 );
471 /* Check for errors */
472 %if &httpSuccess ne 1 %then %do;
473 %put ERROR: Could not upload scenario &curr_file_name. with workgroup &curr_workgroup. and history date &curr_history_date. to SAS Risk Scenario Manager. Execution stopped due to errors.;
474 %abort cancel;
475 %end;
476 %end;
477%mend;
478
479/* Macro to process each scenario by loading into RSM and then creating a MRS in RGF */
480%macro process_scenarios(scen_info_table=);
481 %if %rsk_dsexist(&scen_info_table.) %then %do;
482 /* Get the distinct list of scenarios */
483 proc sql;
484 create table mrs_scenarios as
485 select distinct workgroup
486 , mrs_name
487 , mrs_short_name
488 , mrs_description
489 , multiForecastFlg
490 from &scen_info_table.;
491 quit;
492 /* Get the number of files to process */
493 %let num_scenarios = %rsk_attrn(mrs_scenarios, nlobs);
494 /* Loop through each scenario and create the corresponding MRS */
495 %do s = 1 %to &num_scenarios.;
496 /* Delete the work table if it exists */
497 proc datasets lib=work nolist nowarn;
498 delete curr_mrs_data;
499 run;
500
501 /* Add filter info */
502 data mrs_scenarios_enriched;
503 length filterExp $1024.;
504 set &scen_info_table.;
505 filterExp = "name=" || strip(tab_name) || "%nrstr(&)workGroup=" || strip(workgroup);
506 run;
507
508 /* Get the current scenario info */
509 data _null_;
510 set mrs_scenarios (firstobs = &s. obs=%eval(&s.));
511 call symputx("curr_workgroup", workgroup, "L");
512 call symputx("curr_mrs_name", mrs_name, "L");
513 call symputx("curr_mrs_short_name", mrs_short_name, "L");
514 call symputx("curr_mrs_desc", mrs_description, "L");
515 call symputx("curr_multiForecastFlg", multiForecastFlg, "L");
516 run;
517
518 /* See if an MRS already exists with the current MRS name */
519 %let ticket =;
520 %irm_rest_get_rgf_mrs(host = &host.
521 , server = &server.
522 , solution = &solution.
523 , port = &port.
524 , tgt_ticket = &rgf_tgt_ticket.
525 , filter = filter=eq(name,%27&curr_mrs_name.%27)
526 , details_flg = N
527 , outds = curr_mrs_data
528 , outVarTicket = ticket
529 , outSuccess = httpSuccess
530 , outResponseStatus = responseStatus
531 );
532 /* If an MRS already exists with the same name, then skip and throw a warning */
533 %if(%rsk_attrn(curr_mrs_data, nlobs) ne 0) %then %do;
534 %put WARNING: A Master Risk Scenario with the name &curr_mrs_name. already exists. Skipping the creation of this MRS.;
535 %end;
536 /* Otherwise, create the master risk scenario in RGF */
537 %else %do;
538 %let this_filter = ;
539 %let this_forecastTime = ;
540 proc sql noprint;
541 select
542 filterExp
543 ,forecast_time
544 into
545 :this_filter separated by ','
546 ,:this_forecastTime separated by ','
547 from
548 mrs_scenarios_enriched
549 where
550 mrs_name eq "&curr_mrs_name."
551 ;
552 quit;
553
554 /* Check for multi=forecast flag */
555 %let ticket =;
556 %let httpSuccess=;
557 %let responseStatus=;
558 %irm_rest_create_rgf_mrs(host = &host.
559 , server = &server.
560 , solution = &solution.
561 , port = &port.
562 , tgt_ticket = &rgf_tgt_ticket.
563 , name = &curr_mrs_name.
564 , description = &curr_mrs_desc.
565 , mrsShortName = &curr_mrs_short_name.
566 , multiForecastFlg = &curr_multiForecastFlg.
567 , forecastTime = %superq(this_forecastTime)
568 , scenario_filters = %superq(this_filter)
569 , dimensional_points = &dim_point_key.
570 , outds = master_risk_scenario_&s.
571 , outVarTicket = ticket
572 , outSuccess = httpSuccess
573 , outResponseStatus = responseStatus
574 );
575 /* Check for errors */
576 %if &httpSuccess ne 1 %then %do;
577 %put ERROR: Could not create Master Risk Scenario for scenario &curr_mrs_name.. Execution stopped due to errors.;
578 %abort cancel;
579 %end;
580 %end;
581 %end; /* end %do s = 1 %to &num_scenarios.; */
582 %end; /* end input table exists */
583%mend;
584
585/* Call the macros to import the RSM scenario and create the RGF master risk scenarios */
586%import_rsm_scenarios(scen_info_table=scen_info);
587%process_scenarios(scen_info_table=scen_info);
588
589/* ---------------------------------------------------------------------------- */
590/* Create Segmentation Schemes */
591/* ---------------------------------------------------------------------------- */
592
593%macro create_new_seg_schemes();
594 /* Initialize tot_cycles to 0 in case all seg shcemes are commented out */
595 %let tot_seg_schemes = 0;
596 /* Read the cycle information */
597 data _null_;
598 set seg_schemes end=last;
599 call symputx(cats("seg_name_", put(_N_, 8.)), name, "L");
600 call symputx(cats("seg_description_", put(_N_, 8.)), description, "L");
601 call symputx(cats("seg_variables_", put(_N_, 8.)), segmentation_variables, "L");
602 call symputx(cats("schema_name_", put(_N_, 8.)), schema_name, "L");
603 call symputx(cats("schema_version_", put(_N_, 8.)), schema_version, "L");
604 if last then
605 call symputx("tot_seg_schemes", _N_, "L");
606 run;
607 %do c = 1 %to &tot_seg_schemes.;
608 /* Check if a segmentation scheme with the given name already exists */
609 %let ticket =;
610 %let httpSuccess=;
611 %let responseStatus=;
612 %irm_rest_get_rgf_basic_info( object_uri = segments
613 , host = &host.
614 , port = &port.
615 , tgt_ticket = &rgf_tgt_ticket.
616 , filter = filter=eq(name,%27&&seg_name_&c..%27)
617 , outds = existing_seg_scheme_&c.
618 , outVarTicket = ticket
619 , outSuccess = httpSuccess
620 , outResponseStatus = responseStatus
621 );
622 %if(%rsk_attrn(existing_seg_scheme_&c., nlobs) ne 0) %then %do;
623 %put WARNING: A Segmentation Scheme with the name &&seg_name_&c.. already exists. Skipping the creation of this segmentation scheme.;
624 %end;
625 %else %do;
626 /* Create segmentation schemes for the current row*/
627 %let ticket =;
628 %let httpSuccess=;
629 %let responseStatus=;
630 %irm_rest_create_rgf_seg_scheme(host = &host.
631 , port = &port.
632 , tgt_ticket = &rgf_tgt_ticket.
633 , name = &&seg_name_&c.
634 , description = &&seg_description_&c.
635 , dimensional_points = &dim_point_key.
636 , segmentVariables = %bquote(&&seg_variables_&c.)
637 , schemaName = &&schema_name_&c.
638 , schemaVersion = &&schema_version_&c.
639 , outds = segmentation_scheme_&c.
640 , outVarTicket = ticket
641 , outSuccess = httpSuccess
642 , outResponseStatus = responseStatus
643 );
644 /* Check for errors */
645 %if &httpSuccess ne 1 or %rsk_attrn(segmentation_scheme_&c., NLOBS) eq 0 %then %do;
646 %put ERROR: Could not create segmentation scheme with name &&seg_name_&c... Execution stopped due to errors.;
647 %abort cancel;
648 %end;
649 %end;
650 %end;
651%mend;
652
653/* -------------------------------------------------------------------------- */
654/* Create Allocation Schemes */
655/* -------------------------------------------------------------------------- */
656
657%macro create_new_alloc_schemes();
658 /* Initialize tot_cycles to 0 in case all alloc shcemes are commented out */
659 %let tot_alloc_schemes = 0;
660 /* Read the cycle information */
661 data _null_;
662 set alloc_schemes end=last;
663 call symputx(cats("alloc_name_", put(_N_, 8.)), name, "L");
664 call symputx(cats("alloc_description_", put(_N_, 8.)), description, "L");
665 call symputx(cats("strategyMethod_", put(_N_, 8.)), strategyMethod, "L");
666 call symputx(cats("segScheme_lookup_", put(_N_, 8.)), segScheme_lookup, "L");
667 call symputx(cats("synthInstAllocation_lookup_", put(_N_, 8.)), synthInstAllocation_lookup, "L");
668 call symputx(cats("segmentationVars_", put(_N_, 8.)), segmentationVars, "L");
669 call symputx(cats("synthInst_lookup_", put(_N_, 8.)), synthInst_lookup, "L");
670 if last then
671 call symputx("tot_alloc_schemes", _N_, "L");
672 run;
673 %do c = 1 %to &tot_alloc_schemes.;
674 /* Check if an allocation scheme with the given name already exists */
675 %let ticket =;
676 %let httpSuccess=;
677 %let responseStatus=;
678 %irm_rest_get_rgf_basic_info( object_uri = allocationSchemes
679 , host = &host.
680 , port = &port.
681 , tgt_ticket = &rgf_tgt_ticket.
682 , filter = filter=eq(name,%27&&alloc_name_&c..%27)
683 , outds = existing_alloc_scheme_&c.
684 , outVarTicket = ticket
685 , outSuccess = httpSuccess
686 , outResponseStatus = responseStatus
687 );
688 %if(%rsk_attrn(existing_alloc_scheme_&c., nlobs) ne 0) %then %do;
689 %put WARNING: An Allocation Scheme with the name &&alloc_name_&c.. already exists. Skipping the creation of this allocation scheme.;
690 %end;
691 %else %do;
692 /* Subset the synthetic inst allocations based on the lookup value */
693 %if("" ne "&&synthInstAllocation_lookup_&c.") %then %do;
694 data synthInstAllocations_&c.;
695 set synthInstAllocations;
696 where "&&synthInstAllocation_lookup_&c." eq synthInstAllocation_lookup;
697 drop synthInstAllocation_lookup;
698 run;
699 %end;
700 /* Create allocation schemes for the current row*/
701 %let ticket =;
702 %let httpSuccess=;
703 %let responseStatus=;
704 %irm_rest_create_rgf_alloc_scheme(host = &host.
705 , port = &port.
706 , server = &server.
707 , perspective = %lowcase(&perspective)
708 , tgt_ticket = &rgf_tgt_ticket.
709 , name = &&alloc_name_&c.
710 , description = &&alloc_description_&c.
711 , segSchemeFilter = eq(name,%27&&segScheme_lookup_&c.%27)
712 , method = &&strategyMethod_&c.
713 %if(%sysfunc(exist(synthInstAllocations))) %then %do;
714 , allocationToInstruments = synthInstAllocations_&c.
715 %end;
716 , synthInstFilter = eq(name, %27&&synthInst_lookup_&c.%27)
717 , outds = outAlloc
718 , outVarTicket = ticket
719 , outSuccess = httpSuccess
720 , outResponseStatus = httpResponseStatus
721 );
722 /* Check for errors */
723 %if &httpSuccess ne 1 or %rsk_attrn(outAlloc, NLOBS) eq 0 %then %do;
724 %put ERROR: Could not create allocation scheme with name &&alloc_name_&c... Execution stopped due to errors.;
725 %abort cancel;
726 %end;
727 %end;
728 %end;
729%mend;
730
731/* ---------------------------------------------------------------------------- */
732/* Macro to create given object instance */
733/* ---------------------------------------------------------------------------- */
734
735%macro create_object_instance( collectionName =
736 , custObjNum =
737 , runFinalize = false
738 , sourceSystemCd = RMC
739 , objName =
740 , objDesc =
741 , dimensional_points =
742 , custFieldsFileref =
743 , status = outSuccess
744 );
745 data appends;
746 length value $ 32000 type $ 32;
747
748 value = "{""sourceSystemCd"": ""%upcase(&sourceSystemCd.)"", ""name"":""&objName."", ""description"":""&objDesc.""";
749 type="string";
750 output;
751
752 %if(%sysevalf(%superq(dimensional_points) ne, boolean)) %then %do;
753 value = ", ""dimensionalPoints"": &dimensional_points.";
754 type="string";
755 output;
756 %end;
757
758 value = " , ""customFields"": {";
759 type="string";
760 output;
761
762 value = "&custFieldsFileref.";
763 type="fileref";
764 output;
765
766 value = "}}";
767 type="string";
768 output;
769 run;
770
771 filename _body temp;
772 %irm_append_many(file=_body,append=appends,overwrite=Y);
773
774 %let responseHeader=;
775 data newObj;
776 set _null_;
777 run;
778
779 filename _out temp;
780 %irm_rest_request(url = &host.:&port./&server./rest/&solution.-%lowcase(&perspective.)/&collectionName.
781 , method = POST
782 , server = &server.
783 , tgt_ticket = &rgf_tgt_ticket.
784 , headerIn = Accept:application/json
785 , body = _body
786 , parser = sas.risk.irm.rgf_rest_parser.rmcRestDataDefinition
787 , outds = newObj
788 , fout = _out
789 , outVarTicket = ticket
790 , outSuccess = &status.
791 , outResponseStatus = responseHeader
792 );
793
794 filename _body;
795 filename _out;
796
797 %let new_key=;
798 data _null_;
799 set newObj;
800 call symputX('new_key',key);
801 run;
802
803 %if (%qupcase(&runFinalize.) eq TRUE) %then %do;
804 /* This submit is equivalent to opening and saving in the UI - runs any finalize block code that may be needed */
805 filename payload temp;
806 filename _out temp;
807 %irm_rest_request(url = &host.:&port./&server./rest/&solution.-%lowcase(&perspective.)/uiContexts/&collectionName./&new_key.
808 , method = POST
809 , server = &server.
810 , tgt_ticket = &rgf_tgt_ticket.
811 , headerIn = Accept:application/json
812 , body = %str({"SCREENID": "CustomObject&custObjNum."})
813 , parser =
814 , outds =
815 , fout = payload
816 , outVarTicket = ticket
817 , outSuccess = &status.
818 , outResponseStatus = responseHeader
819 );
820
821 %irm_rest_request(url = &host.:&port./&server./rest/&solution.-%lowcase(&perspective.)/uiContexts/&collectionName./&new_key.
822 , method = PUT
823 , server = &server.
824 , tgt_ticket = &rgf_tgt_ticket.
825 , headerIn = Accept:application/json
826 , body = payload
827 , parser =
828 , outds =
829 , fout = _out
830 , outVarTicket = ticket
831 , outSuccess = &status.
832 , outResponseStatus = responseHeader
833 );
834 filename payload;
835 filename _out;
836 %end;
837%mend create_object_instance;
838
839/* ---------------------------------------------------------------------------- */
840/* Macros to substitute keys in a financial statement projection BEP */
841/* ---------------------------------------------------------------------------- */
842
843%macro substituteFSPkeys(var);
844 &var. = prxchange("s/\-\-SEGSCHEME_OF\-\-/&SEGSCHEME_OF./", -1, &var.);
845 &var. = prxchange("s/\-\-SEGSCHEME_PL\-\-/&SEGSCHEME_PL./", -1, &var.);
846 &var. = prxchange("s/\-\-SEGSCHEME_GL\-\-/&SEGSCHEME_GL./", -1, &var.);
847
848 &var. = prxchange("s/\-\-DATA_OF\-\-/&DATA_OF./", -1, &var.);
849 &var. = prxchange("s/\-\-DATA_PL\-\-/&DATA_PL./", -1, &var.);
850 &var. = prxchange("s/\-\-DATA_GL\-\-/&DATA_GL./", -1, &var.);
851 &var. = prxchange("s/\-\-DATA_RWA\-\-/&DATA_RWA./", -1, &var.);
852
853 &var. = prxchange("s/\-\-DATAMAP_OF\-\-/&DATAMAP_OF./", -1, &var.);
854 &var. = prxchange("s/\-\-DATAMAP_PL\-\-/&DATAMAP_PL./", -1, &var.);
855 &var. = prxchange("s/\-\-DATAMAP_GL\-\-/&DATAMAP_GL./", -1, &var.);
856
857 &var. = prxchange("s/\-\-MODEL_FSP\-\-/&MODEL_FSP./", -1, &var.);
858 &var. = prxchange("s/\-\-BEP_BSP\-\-/&BEP_BSP./", -1, &var.);
859%mend substituteFSPkeys;
860
861%macro updateFSPfiles(oldFileRef=
862 ,newFileRef=
863 ,clearOldFileRef=true
864 ,clearNewFileRef=false
865 );
866 data _null_;
867 length text $2000 left $1000 middle $1000 right $1000;
868 right = " ";
869 fileout = fopen("&newFileRef.","O",1000,"B");
870 filein = fopen("&oldFileRef.",'I',1000,"B");
871 do while(fread(filein)=0);
872 rc = fget(filein,text,1000);
873 text = strip(right) || strip(text);
874 len = length(text);
875 half = floor(len/2);
876 third = floor(len/3);
877
878 left = substr(text,1,half);
879 right = substr(text,half+1);
880 %substituteFSPkeys(left);
881 %substituteFSPkeys(right);
882 text = strip(left) || strip(right);
883
884 left = substr(text,1,third);
885 middle = substr(text,third+1,third);
886 right = substr(text,2*third+1);
887 %substituteFSPkeys(left);
888 %substituteFSPkeys(middle);
889 %substituteFSPkeys(right);
890
891 text = strip(left) || strip(middle);
892 rc = fput(fileout, strip(text));
893 rc =fwrite(fileout);
894 end;
895
896 rc = fput(fileout, strip(right));
897 rc =fwrite(fileout);
898
899 rc = fclose(fileout);
900 rc = fclose(filein);
901 run;
902 %if ("&clearOldFileRef." eq "true") %then %do;
903 filename &oldFileRef.;
904 %end;
905 %if ("&clearNewFileRef." eq "true") %then %do;
906 filename &newFileRef.;
907 %end;
908%mend;
909
910/* -------------------------------------------------------------------------------- */
911/* Create Business Evolution Plans */
912/* -------------------------------------------------------------------------------- */
913
914%macro create_new_bus_evolution_plans();
915 /* Initialize tot_cycles to 0 in case all business evolution plans are commented out */
916 %let tot_business_evol_plans = 0;
917 /* Read the cycle information */
918 data _null_;
919 set bus_evolution_plans end=last;
920 call symputx(cats("bus_evol_name_", put(_N_, 8.)), name, "L");
921 call symputx(cats("bus_evol_description_", put(_N_, 8.)), description, "L");
922 call symputx(cats("BEPDetails_file_", put(_N_, 8.)), BEPDetails_file, "L");
923 call symputx(cats("planningData_lookup_", put(_N_, 8.)), planningData_lookup, "L");
924 call symputx(cats("allocationScheme_lookup_", put(_N_, 8.)), allocationScheme_lookup, "L");
925 call symputx(cats("bepType_", put(_N_, 8.)), bepType, "L");
926 call symputx(cats("segScheme_OF_lookup_", put(_N_, 8.)), segScheme_OF_lookup, "L");
927 call symputx(cats("segScheme_PL_lookup_", put(_N_, 8.)), segScheme_PL_lookup, "L");
928 call symputx(cats("segScheme_GL_lookup_", put(_N_, 8.)), segScheme_GL_lookup, "L");
929 call symputx(cats("data_OF_lookup_", put(_N_, 8.)), data_OF_lookup, "L");
930 call symputx(cats("data_PL_lookup_", put(_N_, 8.)), data_PL_lookup, "L");
931 call symputx(cats("data_GL_lookup_", put(_N_, 8.)), data_GL_lookup, "L");
932 call symputx(cats("data_RWA_lookup_", put(_N_, 8.)), data_RWA_lookup, "L");
933 call symputx(cats("dataMap_OF_lookup_", put(_N_, 8.)), dataMap_OF_lookup, "L");
934 call symputx(cats("dataMap_PL_lookup_", put(_N_, 8.)), dataMap_PL_lookup, "L");
935 call symputx(cats("dataMap_GL_lookup_", put(_N_, 8.)), dataMap_GL_lookup, "L");
936 call symputx(cats("model_FSP_lookup_", put(_N_, 8.)), model_FSP_lookup, "L");
937 if last then
938 call symputx("tot_business_evol_plans", _N_, "L");
939 run;
940
941 %do c = 1 %to &tot_business_evol_plans.;
942 /* Check if a BEP with the given name already exists */
943 %let ticket =;
944 %let httpSuccess=;
945 %let responseStatus=;
946 %irm_rest_get_rgf_basic_info( object_uri = businessEvolutionPlans
947 , host = &host.
948 , port = &port.
949 , tgt_ticket = &rgf_tgt_ticket.
950 , filter = filter=eq(name,%27&&bus_evol_name_&c..%27)
951 , outds = existing_bep_&c.
952 , outVarTicket = ticket
953 , outSuccess = httpSuccess
954 , outResponseStatus = responseStatus
955 );
956 %if(%rsk_attrn(existing_bep_&c., nlobs) ne 0) %then %do;
957 %put WARNING: A Business Evolution Plan with the name &&bus_evol_name_&c.. already exists. Skipping the creation of this BEP.;
958 %end;
959 %else %do;
960 /* If BEP type is financial statement proj then replace the keys in the BEP details */
961 %if ("&&bepType_&c.." eq "FINSTATEMENT") %then %do;
962 /* Get the segmentation scheme keys */
963 %let seg_of_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&segScheme_OF_lookup_&c..));
964 %let seg_pl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&segScheme_PL_lookup_&c..));
965 %let seg_gl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&segScheme_GL_lookup_&c..));
966 %let seg_scheme_filter = in(name,%27&&seg_of_name_&c..%27,%27&&seg_pl_name_&c..%27,%27&&seg_gl_name_&c..%27)%nrstr(&sortBy=key&fields=name,key);
967 %let httpSuccess=;
968 %let responseStatus=;
969 %irm_rest_get_rgf_basic_info( object_uri = segments
970 , host = &host.
971 , port = &port.
972 , tgt_ticket = &rgf_tgt_ticket.
973 , filter = filter=&seg_scheme_filter.
974 , outds = seg_schemes_&c.
975 , outVarTicket = ticket
976 , outSuccess = httpSuccess
977 , outResponseStatus = responseStatus
978 );
979 %if &httpSuccess ne 1 %then %do;
980 %put ERROR: Could not find segmentation schemes for specified lookup keys. Execution stopped due to errors.;
981 %abort cancel;
982 %end;
983 data _null_;
984 set seg_schemes_&c.;
985 if(name eq "&&segScheme_OF_lookup_&c..") then
986 call symputX('SEGSCHEME_OF',key);
987 if(name eq "&&segScheme_PL_lookup_&c..") then
988 call symputX('SEGSCHEME_PL',key);
989 if(name eq "&&segScheme_GL_lookup_&c..") then
990 call symputX('SEGSCHEME_GL',key);
991 run;
992 /* Get the analysis data keys */
993 %let data_of_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&data_OF_lookup_&c..));
994 %let data_pl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&data_PL_lookup_&c..));
995 %let data_gl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&data_GL_lookup_&c..));
996 %let data_rwa_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&data_RWA_lookup_&c..));
997 %let data_filter = in(name,%27&&data_of_name_&c..%27,%27&&data_pl_name_&c..%27,%27&&data_gl_name_&c..%27,%27&&data_rwa_name_&c..%27)%nrstr(&sortBy=key&fields=name,key);
998 %let httpSuccess=;
999 %let responseStatus=;
1000 %irm_rest_get_rgf_basic_info( object_uri = analysisData
1001 , host = &host.
1002 , port = &port.
1003 , tgt_ticket = &rgf_tgt_ticket.
1004 , filter = filter=&data_filter.
1005 , outds = analysis_data_&c.
1006 , outVarTicket = ticket
1007 , outSuccess = httpSuccess
1008 , outResponseStatus = responseStatus
1009 );
1010 %if &httpSuccess ne 1 %then %do;
1011 %put ERROR: Could not find analysis data instances for specified lookup keys. Execution stopped due to errors.;
1012 %abort cancel;
1013 %end;
1014 data _null_;
1015 set analysis_data_&c.;
1016 if(name eq "&&data_OF_lookup_&c..") then
1017 call symputX('DATA_OF',key);
1018 if(name eq "&&data_PL_lookup_&c..") then
1019 call symputX('DATA_PL',key);
1020 if(name eq "&&data_GL_lookup_&c..") then
1021 call symputX('DATA_GL',key);
1022 if(name eq "&&data_RWA_lookup_&c..") then
1023 call symputX('DATA_RWA',key);
1024 run;
1025 /* Get the data map keys */
1026 %let map_of_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&dataMap_OF_lookup_&c..));
1027 %let map_pl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&dataMap_PL_lookup_&c..));
1028 %let map_gl_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&dataMap_GL_lookup_&c..));
1029 %let data_map_filter = in(name,%27&&map_of_name_&c..%27,%27&&map_pl_name_&c..%27,%27&&map_gl_name_&c..%27)%nrstr(&sortBy=key&fields=name,key);
1030 %let httpSuccess=;
1031 %let responseStatus=;
1032 %irm_rest_get_rgf_basic_info( object_uri = dataMaps
1033 , host = &host.
1034 , port = &port.
1035 , tgt_ticket = &rgf_tgt_ticket.
1036 , filter = filter=&data_map_filter.
1037 , outds = data_maps_&c.
1038 , outVarTicket = ticket
1039 , outSuccess = httpSuccess
1040 , outResponseStatus = responseStatus
1041 );
1042 %if &httpSuccess ne 1 %then %do;
1043 %put ERROR: Could not find data maps for specified lookup keys. Execution stopped due to errors.;
1044 %abort cancel;
1045 %end;
1046 data _null_;
1047 set data_maps_&c.;
1048 if(name eq "&&dataMap_OF_lookup_&c..") then
1049 call symputX('DATAMAP_OF',key);
1050 if(name eq "&&dataMap_PL_lookup_&c..") then
1051 call symputX('DATAMAP_PL',key);
1052 if(name eq "&&dataMap_GL_lookup_&c..") then
1053 call symputX('DATAMAP_GL',key);
1054 run;
1055 /* Get the model key */
1056 %let model_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&model_FSP_lookup_&c..));
1057 %let model_filter = eq(name,%27&&model_FSP_lookup_&c..%27)%nrstr(&sortBy=key&fields=name,key);
1058 %let httpSuccess=;
1059 %let responseStatus=;
1060 %irm_rest_get_rgf_basic_info( object_uri = models
1061 , host = &host.
1062 , port = &port.
1063 , tgt_ticket = &rgf_tgt_ticket.
1064 , filter = filter=&model_filter.
1065 , outds = models_&c.
1066 , outVarTicket = ticket
1067 , outSuccess = httpSuccess
1068 , outResponseStatus = responseStatus
1069 );
1070 %if &httpSuccess ne 1 %then %do;
1071 %put ERROR: Could not find model for specified lookup keys. Execution stopped due to errors.;
1072 %abort cancel;
1073 %end;
1074 data _null_;
1075 set models_&c.;
1076 if(name eq "&&model_FSP_lookup_&c..") then
1077 call symputX('MODEL_FSP',key);
1078 run;
1079 /* Get the key of the new BEP that will be created */
1080 /* NOTE: If there are no existing BEPs, the key will be missing and the BEP will not be created (or won't be created correctly) */
1081 %let bep_filter = %nrstr(sortBy=key:descending&limit=1&fields=name,key);
1082 %let httpSuccess=;
1083 %let responseStatus=;
1084 %irm_rest_get_rgf_basic_info( object_uri = businessEvolutionPlans
1085 , host = &host.
1086 , port = &port.
1087 , tgt_ticket = &rgf_tgt_ticket.
1088 , filter = &bep_filter.
1089 , outds = beps_&c.
1090 , outVarTicket = ticket
1091 , outSuccess = httpSuccess
1092 , outResponseStatus = responseStatus
1093 );
1094 %if &httpSuccess ne 1 %then %do;
1095 %put ERROR: Could not find any existing business evolution plans. At least one BEP is needed in order to grab the proper key for the new BEP. Execution stopped due to errors.;
1096 %abort cancel;
1097 %end;
1098 data _null_;
1099 set beps_&c. end=last;
1100 if last then do;
1101 call symputX('BEP_BSP',key+1);
1102 end;
1103 run;
1104 /* Perform parameter replacement in the BEP Details */
1105 filename origDtl "&&BEPDetails_file_&c..";
1106 filename bepDtl&c. temp;
1107 %updateFSPfiles(oldFileRef=origDtl
1108 ,newFileRef=bepDtl&c.
1109 ,clearOldFileRef=true
1110 ,clearNewFileRef=false
1111 );
1112 %end;
1113 /* If BEP type is portfolio proj then add the planning data and alloc scheme keys */
1114 %else %do;
1115 /* Get the planning data key */
1116 %let plan_data_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&planningData_lookup_&c..));
1117 %let adata_filter = in(name,%27&&plan_data_name_&c..%27)%nrstr(&sortBy=key&fields=name,key);
1118 %let httpSuccess=;
1119 %let responseStatus=;
1120 %irm_rest_get_rgf_basic_info( object_uri = analysisData
1121 , host = &host.
1122 , port = &port.
1123 , tgt_ticket = &rgf_tgt_ticket.
1124 , filter = filter=&adata_filter.
1125 , outds = adata_&c.
1126 , outVarTicket = ticket
1127 , outSuccess = httpSuccess
1128 , outResponseStatus = responseStatus
1129 );
1130 %if &httpSuccess ne 1 %then %do;
1131 %put ERROR: Could not find planning data for specified lookup key. Execution stopped due to errors.;
1132 %abort cancel;
1133 %end;
1134 data _null_;
1135 set adata_&c.;
1136 if(name eq "&&planningData_lookup_&c..") then
1137 call symputX('plan_data_key',key);
1138 run;
1139 /* Get the allocation scheme key */
1140 %let alloc_scheme_name_&c. = %sysfunc(prxchange(s/%nrstr(&)/%nrstr(%26)/i, -1, &&allocationScheme_lookup_&c..));
1141 %let alloc_scheme_filter = in(name,%27&&alloc_scheme_name_&c..%27)%nrstr(&sortBy=key&fields=name,key);
1142 %let httpSuccess=;
1143 %let responseStatus=;
1144 %irm_rest_get_rgf_basic_info( object_uri = allocationSchemes
1145 , host = &host.
1146 , port = &port.
1147 , tgt_ticket = &rgf_tgt_ticket.
1148 , filter = filter=&alloc_scheme_filter.
1149 , outds = alloc_schemes_&c.
1150 , outVarTicket = ticket
1151 , outSuccess = httpSuccess
1152 , outResponseStatus = responseStatus
1153 );
1154 %if &httpSuccess ne 1 %then %do;
1155 %put ERROR: Could not find allocation scheme for specified lookup key. Execution stopped due to errors.;
1156 %abort cancel;
1157 %end;
1158 data _null_;
1159 set alloc_schemes_&c.;
1160 if(name eq "&&allocationScheme_lookup_&c..") then
1161 call symputX('allocKey',key);
1162 run;
1163 /* Assign the filename for the bep details */
1164 filename bepDtl&c. "&&BEPDetails_file_&c..";
1165 %end;
1166 /* Create the custom field definitions file for the BEP */
1167 filename bepFlds&c. temp;
1168 filename bepPost&c. temp;
1169 data _null_;
1170 file bepFlds&c.;
1171 set work.bus_evolution_plans;
1172 if _N_ = %eval(&c.) then do;
1173 %if ("&&bepType_&c.." eq "PORTFOLIO") %then %do;
1174 put '"planningDataKey": ' "&plan_data_key." ',';
1175 put '"allocationSchemeKey": ' "&allocKey." ',';
1176 %end;
1177 put '"bepShortName": "' bepShortName+(-1) '",';
1178 put '"interval": "' interval+(-1) '",';
1179 put '"intervalCount": ' intervalCount+(-1) ',';
1180 put '"solutionCreatedIn": "' "%upcase(&perspective.)" '",';
1181 end;
1182 run;
1183 %let bep_post_fileref=bepPost&c.;
1184 data _null_;
1185 file &bep_post_fileref.;
1186 set work.bus_evolution_plans;
1187 if _N_ = %eval(&c.) then do;
1188 if not missing(planDataSegsAndTargets) then
1189 put '"planDataSegsAndTargets": "' planDataSegsAndTargets+(-1) '",';
1190 if allocationFlg eq 1 then
1191 put '"allocationFlg": true,';
1192 else
1193 put '"allocationFlg": false,';
1194 put '"bepType": "' bepType+(-1) '",';
1195 if not missing(segmentationVars) then
1196 put '"segmentationVars": "' segmentationVars+(-1) '",';
1197 if not missing(targetVariables) then
1198 put '"targetVariables": "' targetVariables+(-1) '",';
1199 if not missing(lastSelectedTargetVariable) then
1200 put '"lastSelectedTargetVariable": "' lastSelectedTargetVariable+(-1) '"';
1201 if not missing(bepVarsInfo) then
1202 put '"bepVarsInfo": "' bepVarsInfo+(-1) '"';
1203 end;
1204 run;
1205 /* For FS projection, perform paramter replacement in the bepPost file (for planDataSegsAndTargets) */
1206 %if ("&&bepType_&c.." eq "FINSTATEMENT") %then %do;
1207 filename newPost&c. temp;
1208 %updateFSPfiles(oldFileRef=&bep_post_fileref.;
1209 ,newFileRef=newPost&c.
1210 ,clearOldFileRef=true
1211 ,clearNewFileRef=false
1212 );
1213 %let bep_post_fileref=newPost&c.;
1214 %end;
1215 data append;
1216 length value $ 32000 type $ 32;
1217 value = '"BEPDetails": "'; type="string"; output;
1218 value = "bepDtl&c."; type="fileref"; output;
1219 value = '",'; type="string"; output;
1220 value = ""; type="newline"; output;
1221 value = "&bep_post_fileref."; type="fileref"; output;
1222 run;
1223 %irm_append_many(file=bepFlds&c.,append=append);
1224 /* Create business evolution plans for the current row */
1225 %let ticket =;
1226 %let httpSuccess=;
1227 %let responseStatus=;
1228 %create_object_instance( collectionName = businessEvolutionPlans
1229 , custObjNum = 207
1230 , runFinalize = true
1231 , objName = &&bus_evol_name_&c.
1232 , objDesc = &&bus_evol_description_&c.
1233 , dimensional_points = &dim_point_key.
1234 , custFieldsFileref = bepFlds&c.
1235 , status =
1236 );
1237 filename bepFlds&c. clear;
1238 filename bepPost&c. clear;
1239 filename bepDtl&c. clear;
1240 %end;
1241 %end;
1242%mend;
1243
1244/* ------------------------------------------------------------------------------------------------- */
1245/* Macro to create the link instance for previous period data */
1246/* ------------------------------------------------------------------------------------------------- */
1247
1248/* Macro to create the cycle-analysis data link instance for previous period data */
1249%macro create_cycle_prev_data_links(linktype=, data_filter=, cycle_key=);
1250 /* Delete the work table if it exists */
1251 proc datasets lib=work nolist nowarn;
1252 delete __prev_data__;
1253 run;
1254 /* Get the analysis data using the rest filter */
1255 %let ticket = ;
1256 %let httpSuccess=;
1257 %let responseStatus=;
1258 %irm_rest_get_rgf_analysis_data(host = &host.
1259 , server = &server.
1260 , solution = &solution.
1261 , port = &port.
1262 , tgt_ticket = &rgf_tgt_ticket.
1263 , filter = filter=&data_filter.
1264 , outds = __prev_data__
1265 , outVarTicket = ticket
1266 , outSuccess = httpSuccess
1267 , outResponseStatus = responseStatus
1268 );
1269 /* Check for errors */
1270 %if &httpSuccess. ne 1 %then %do;
1271 %put ERROR: No analysis data instances found using rest filter &data_filter.;
1272 %abort cancel;
1273 %end;
1274 /* Get the prev FRHTM data key */
1275 %let prev_data_key =;
1276 data _null_;
1277 set __prev_data__(obs = 1);
1278 call symputx("prev_data_key", key, "L");
1279 run;
1280 /* Create the link instance */
1281 %let ticket = ;
1282 %let httpSuccess=;
1283 %let responseStatus=;
1284 %irm_rest_create_rgf_link_inst(host = &host.
1285 , port = &port.
1286 , server = &server.
1287 , solution = &solution.
1288 , tgt_ticket = &rgf_tgt_ticket.
1289 , link_type = &linktype.
1290 , business_object1 = &cycle_key.
1291 , business_object2 = &prev_data_key.
1292 , outds = objectLink
1293 , outVarTicket = ticket
1294 , outSuccess = httpSuccess
1295 , outResponseStatus = responseStatus
1296 );
1297 /* Check for errors */
1298 %if &httpSuccess. ne 1 %then %do;
1299 %put ERROR: Could not create link instance for link type &linktype. with analysis data &data_key. and cycle &cycle_key.;
1300 %abort cancel;
1301 %end;
1302 /* Create the link instance */
1303 %let ticket = ;
1304 %let httpSuccess=;
1305 %let responseStatus=;
1306 %irm_rest_create_rgf_link_inst(host = &host.
1307 , port = &port.
1308 , server = &server.
1309 , solution = &solution.
1310 , tgt_ticket = &rgf_tgt_ticket.
1311 , link_type = cycle_analysisData_prev
1312 , business_object1 = &cycle_key.
1313 , business_object2 = &prev_data_key.
1314 , outds = objectLink
1315 , outVarTicket = ticket
1316 , outSuccess = httpSuccess
1317 , outResponseStatus = responseStatus
1318 );
1319 /* Check for errors */
1320 %if &httpSuccess. ne 1 %then %do;
1321 %put ERROR: Could not create link instance for link type cycle_analysisData_prev with analysis data &data_key. and cycle &cycle_key.;
1322 %abort cancel;
1323 %end;
1324%mend;
1325
1326/* ------------------------------------------------------------------------------------------------- */
1327/* Macro to get the cycle information from the param table */
1328/* ------------------------------------------------------------------------------------------------- */
1329
1330%macro read_cycle_info_for_task(task_number);
1331 /* Get the cycle filter info for the current task */
1332 data cycle_filter (drop = id: pattern);
1333 set workflow;
1334 if _n_ = &task_number.;
1335 if cycle ne '' then do;
1336 if prxmatch('/.*objectLinks.*\[(.*)\].*/', cycle) then do;
1337 call symputx('_objectLinks_', prxchange('s/.*objectLinks.*\[(.*)\].*/$1/', 1, cycle));
1338 end;
1339 else do;
1340 /* TODO: get the workflow template key from a macro var parameter instead of hardcoding to 10000 */
1341 call symputx('_objectLinks_', '%bquote({"linkTypeId": "wfTemplate_cycle", "businessObject1": 10000})');
1342 end;
1343 pattern = prxparse('s/(\{.*)("objectLinks".*\[.*\])(.*\})/$1$3/');
1344 call prxchange(pattern, -1, cycle);
1345 if prxmatch("/\ACUST_OBJ_\d{1,3}\|\d{5}\|rmc\|\z/", strip(cycle)) = 1 then do;
1346 call symputx('_cycle_filter_', cats('key=', scan(cycle, 2, '|')), 'G');
1347 end;
1348 else if prxmatch('/\A\d{5}\z/', strip(cycle)) = 1 then do;
1349 call symputx('_cycle_filter_', cats('key=', cycle), 'G');
1350 end;
1351 else do;
1352 id1 = prxparse('s/\s*:\s*/=/i');
1353 call prxchange(id1, -1, cycle);
1354 id2 = prxparse('s/\s*"\s*//i');
1355 call prxchange(id2, -1, cycle);
1356 id3 = prxparse('s/\s*,\s*/%nrstr(&)/i');
1357 call prxchange(id3, -1, cycle);
1358 id4 = prxparse('s/[\[{}\]]//i');
1359 call prxchange(id4, -1, cycle);
1360 id5 = prxparse('s/cycleId\s*=/objectId=/i');
1361 call prxchange(id5, -1, cycle);
1362 call symputx('_cycle_filter_', cycle, 'G');
1363 end;
1364 end;
1365 run;
1366 %put &=_cycle_filter_;
1367 /* Retrieve the cycle using the filter from above */
1368 %let ticket =;
1369 %irm_rest_get_rgf_cycle(host = &host.
1370 , port = &port.
1371 , server = &server.
1372 , tgt_ticket = &rgf_tgt_ticket.
1373 , filter = &_cycle_filter_.
1374 , outds = cycle_ds
1375 );
1376 /* If the cycle does not exist, throw an error and abort */
1377 %if %rsk_attrn(cycle_ds, nobs) = 0 %then %do;
1378 %put ERROR: No cycles found using filter &_cycle_filter_.. Aborting execution.;
1379 %abort cancel;
1380 %end;
1381
1382 /* Get the cycle key from the cycle_ds */
1383 %let cycle_key =;
1384 data _null_;
1385 set cycle_ds (obs = 1);
1386 call symputx("cycle_key", key);
1387 run;
1388%mend;
1389
1390/* ------------------------------------------------------------------------------------------------- */
1391/* Execute the cycle */
1392/* ------------------------------------------------------------------------------------------------- */
1393
1394%macro run_cycle;
1395 /* Read the workflow table */
1396 %read_workflow_table(filePath=&param_table_path.
1397 , fileName=&param_table_name.);
1398 %let total_tasks = %rsk_attrn(workflow, nobs);
1399 %let task_number = 1;
1400 /* Loop through each task in the workflow table */
1401 %do %while (&task_number. le &total_tasks.);
1402 /* Read the workflow table - we shouldn't have to do this in each loop but unfortunately the
1403 irm_rest_rgf_cycle_run_task macro deletes all work tables */
1404 %read_workflow_table(filePath=&param_table_path.
1405 , fileName=&param_table_name.);
1406 /* Get the cycle information for the current task */
1407 %let cycle_key=;
1408 %read_cycle_info_for_task(task_number = &task_number.);
1409 %put NOTE: Cycle filter for task &task_number. is &_cycle_filter_.;
1410 %put NOTE: Cycle key for task &task_number. is &cycle_key.;
1411 /* Get the task information for the current task */
1412 data _null_;
1413 set workflow (firstobs = &task_number. obs = &task_number.);
1414 call symputx('cycle', cycle);
1415 call symputx('task_for_parameters', task_for_parameters);
1416 call symputx('activity_choice', activity_choice);
1417 call symputx('transition_choice', transition_choice);
1418 call symputx('analysisRunTitle', analysisRunTitle);
1419 call symputx('waitFlg', waitFlg);
1420 call symputx('control_param_lookup_key', control_param_lookup_key);
1421 call symputx('create_objects', create_objects);
1422 /* If a value was provided for the create_link_instances column, parse the contents to get the link type and filter */
1423 if not missing(create_link_instances) then do;
1424 call symputx('create_link_flg', 'Y', "L");
1425 num_linktypes = countc(create_link_instances, '{');
1426 call symputx('num_linktypes', num_linktypes, "G");
1427 do i = 1 to num_linktypes;
1428 curr_link_info = scan(scan(create_link_instances,i,'{'),1,'}');
1429 call symputx(cats('linktype_',put(i,8.)),scan(curr_link_info,1,'='), "G");
1430 call symputx(cats('linkfilter_',put(i,8.)),scan(curr_link_info,2,'"'), "G");
1431 end;
1432 end;
1433 else do;
1434 call symputx('create_link_flg', 'N');
1435 end;
1436 run;
1437 /* If the create_link_instances field is not empty, get the cycle key and create the link instance(s) */
1438 %if &create_link_flg. eq Y %then %do;
1439 /* Loop through each link type and create the link instances */
1440 %do l = 1 %to &num_linktypes.;
1441 %if "&&linkfilter_&l.." ne "" %then %do;
1442 %create_cycle_prev_data_links(linktype=&&linktype_&l.., data_filter=&&linkfilter_&l.., cycle_key=&cycle_key.);
1443 %end;
1444 %end;
1445 %end;
1446 /* Else if the create_objects field is not empty, run the macro to process the specified tab */
1447 %else %if ("&create_objects." ne "") %then %do;
1448 %if %sysmacexist(create_new_&create_objects.) %then %do;
1449 %create_new_&create_objects.();
1450 %end;
1451 %else %do;
1452 %put WARNING: Could not create objects from tab &create_objects. because no corresponding creation macro was found. Skipping this step..;
1453 %end;
1454 %end;
1455 /* Otherwise, execute the task */
1456 %else %do;
1457 %irm_rest_rgf_cycle_run_task(host = &host.
1458 , port = &port.
1459 , server = &server.
1460 , solution = &solution.
1461 , perspective = %lowcase(&perspective.)
1462 , tgt_ticket = &rgf_tgt_ticket.
1463 , cycle = &_cycle_filter_.
1464 , analysisRunTitle = &analysisRunTitle.
1465 , param_table_path = &param_table_path.
1466 , param_table_name = &param_table_name.
1467 , task_for_parameters = &task_for_parameters.
1468 , activity_choice = &activity_choice.
1469 , transition_choice = &transition_choice.
1470 , waitFlg = &waitFlg.
1471 , control_param_lookup_key = &control_param_lookup_key.
1472 );
1473 %end;
1474 /* Increment the task number */
1475 %let task_number = %eval(&task_number + 1);
1476 %end;
1477 /* Done processing all tasks */
1478 %put NOTE: Cycle processing has completed.;
1479%mend;
1480
1481%run_cycle;
1482
1483/* ------------------------------------------------------------------------------------------------- */
1484/* END OF SCRIPT */
1485/* ------------------------------------------------------------------------------------------------- */