Risk Assessment responses aren't always showing in Change Request related list

dhc
Kilo Contributor

We are having an issue whereby the RA responses don't appear within the Change Request related list. I have found that the problematic RA's are the one's that don't have a 'completed by', 'completed date', or 'instance' within the task_assessment table.

find_real_file.png

find_real_file.png

The sequence of events to populate these fields are:

- Clicking the 'Take Risk and Impact Assessment' triggers the UI Action

function invokeAssessment() {

  g_form.hideAllFieldMsgs();

  var count = parseInt(g_form.getValue('u_risk_assessment_count'),0);

  if(isNaN(count)) {

  count = 1;

  } else {

  count++;

  }

  g_form.setValue('u_risk_assessment_count', count);

  var isSubmitted = false;

  var id = g_form.getUniqueValue();

  var ga = new GlideAjax("CreateAssessment");

  ga.addParam("sysparm_name", "checkAssessment");

  ga.addParam("sysparm_id", id);

  ga.addParam("sysparm_class", "change_request");

  ga.getXMLAnswer(function(res) {

  //alert(res);

  if (res == "No Condition")

  g_form.addInfoMessage(getMessage("There are no risk assessments defined for this request"));

  else {

  var resArr = [];

  resArr = res.split(",", 2);

  var taskAsmtID = resArr[0];

  var assessmentName = resArr[1];

  var url = "survey_take.do?sysparm_survey=" + encodeURIComponent(assessmentName);

  url += "&sysparm_task_assessment=" + taskAsmtID;

  url += "&sysparm_survey_update=false";

  url += "&sysparm_stack=no";

  var d = new GlideOverlay({

  title: getMessage("Risk Assessment"),

  iframe: url,

  width: "60%",

  height: "80%",

  onBeforeClose: function() {

  if(isSubmitted)

  return;

  //alert('going to delete asessment');

  var ga = new GlideAjax("CreateAssessment");

  ga.addParam("sysparm_name", "deleteAssessment");

  ga.addParam("sysparm_id", taskAsmtID);

  ga.getXMLWait();

  },

  onAfterLoad: function() {

  d.autoDimension();

  d.autoPosition();

  d._createIframeShim();

  var iframe = d.getIFrameElement();

  var post_button = iframe.contentWindow.document.getElementById("post_survey");

  if (post_button.addEventListener) {

  post_button.addEventListener("click", function(eventObj) {

  if (eventObj.view.mandatoryResult) {

  isSubmitted = true;

  d.close();

  g_form.setValue('u_risk_assessment_status','submitted');

  g_form.clearMessages();

  gsftSubmit(null,g_form.getFormElement(),'risk_and_impact_assessment');

  }

  });

  } else {

  post_button.attachEvent("onclick", function(eventObj) {

  if (iframe.contentWindow.mandatoryResult) {

  isSubmitted = true;

  d.close();

  g_form.setValue('u_risk_assessment_status','submitted');

  g_form.clearMessages();

  gsftSubmit(null,g_form.getFormElement(),'risk_and_impact_assessment');

  }

  });

  }

  }

  });

  d.render();

  }

  });

}

if (typeof window == 'undefined')

// Check if the assessment has an instance or we can't calculate risk and impact.

// Don't proceed until instance is present..

updateAndRedirect();

function updateAndRedirect() {

  // test

  // var scr = new SetChangeRisk();

  // scr.setRisk(current);

  //End test

  current.update();

  var counter = 0;

  var carryOn = false;

  //var grTA =   new GlideRecord('task_assessment');

  //grTA.addEncodedQuery('task='+current.sys_id);

  while(!carryOn) {

  gs.addInfoMessage('Checking for Assessment Instance ' + carryOn + ' ' + counter);

  grTA =   new GlideRecord('task_assessment');

        grTA.addEncodedQuery('task='+current.sys_id);

  grTA.query();

  if(grTA.next()){

  carryOn = (grTA.getValue('instance') != null);

  }

  counter++;

  if(counter == 200) {

  gs.addInfoMessage('Error... No Assessment Instances Found ..');

  current.u_risk_assessment_status = 'not calculated';

  current.update();

  carryOn = true;

  }

  }

  //gs.addInfoMessage('DEBUG - counter is ' + counter);

  //action.setRedirectURL(current);

  var scr = new RiskAssessmentCalculatorEXP();

  var takenRA = '';

  var assessmentMatch = scr.checkForMatchingAssessment(current.sys_class_name, current);

  if (assessmentMatch == '') {

  calcRisk();

  }

  else {

  takenRA = scr.checkForAssessmentInstance(current.sys_id);

  //the correct assessment has been taken

  if (takenRA != '' && takenRA == assessmentMatch){

  calcRisk();

  }

  if (takenRA != '' && takenRA != assessmentMatch){

  gs.addInfoMessage(gs.getMessage('Incorrect risk assessment taken, please fill out a new assessment'));

  }

  if (takenRA == ''){

  gs.addInfoMessage(gs.getMessage('A risk assessment is required, please fill out a risk assessment'));

  }

  }

  function calcRisk() {

  var risk = scr.calculateRisk(current);

  current.update();

  }

  action.setRedirectURL(current);

}

- The url invokes the survey_take UI Page (line 28-35 from above)

<?xml version="1.0" encoding="utf-8" ?>

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

  <j:set var="jvar_inline" value="false"/>

  <j:if test="${RP.isPortal()}">

  <j:set var="jvar_inline" value="true"/>

  </j:if>

  <g:requires name="scripts/js_includes_catalog.js" includes="true" inline='${jvar_inline}'/>

  <g:requires name="styles/js_includes_catalog_v2.css" includes="true"/>

  <g:requires name="styles/sc_cat_only_v2.css" includes="false"/>

  <g:inline template="sc_sanitize.xml"/>

  <j:if test="${GlideMobileExtensions.getDeviceType() != 'doctype'}">

  <g:requires name="scripts/lib/jquery_includes.js" inline="true" />

  </j:if>

  <form name="survey_detail" style="DISPLAY: inline" action="post_survey.do" method="POST">

  <g:evaluate var="jvar_user" expression="gs.getUserID();" />

  <input name="sysparm_survey_user" type="HIDDEN" value="${jvar_user}" />

  <input name="sysparm_survey_update" type="HIDDEN" value="${sysparm_survey_update}" />

  <input name="sysparm_task_survey" type="HIDDEN" value="${sysparm_task_survey}" />

  <input name="sysparm_task_assessment" type="HIDDEN" value="${sysparm_task_assessment}" />

  <input name="sysparm_return_url" type="HIDDEN" value="${sysparm_return_url}" />

  <g2:evaluate var="jvar_item" jelly="true">

  gr = new GlideRecord('survey_master');

  gr.addQuery('name', jelly.sysparm_survey);

  gr.query();

                                              if (!gr.hasNext()) {

                                                      var tt = new GlideRecord("sys_translated_text");

                        tt.addQuery("value", jelly.sysparm_survey);

                        tt.query();

                        if (tt.next()) {

                                                              gr = new GlideRecord('survey_master');

                gr.addQuery("sys_id", tt.documentkey);

                                                              gr.query();

                                                      }

                                              }

  </g2:evaluate>

  <g2:evaluate var="jvar_redirect_to_login">

                                              if (!gs.getUser().isDefault())

                                                      "false";

                                              else if (!gr.hasNext())

                                                      "true";

                                              else if (!GlidePublicPage.isPublic("survey_take"))

                                                      "false";

                                              else {

                                                      gr.next();

                                                      var qs = new GlideRecord("survey_question_new");

                                                      qs.addActiveQuery();

                                                      qs.addQuery("master", gr.sys_id);

                                                      qs.query("read_roles", "public");

                                                      gr.setLocation(-1);

                                                      if (qs.getRowCount() > 0)

                                                              "false";

                                                      else

                                                              "true";

                                              }

  </g2:evaluate>

  <table class="wide">

  <j2:if test="$[gr.next()]">

                                                      <j2:if test="$[!jvar_redirect_to_login]">

  <tr class="header"><td colspan="2">

  <div class="survey caption">

                                                                    $[NS:gr.name.getDisplayValue()]

                                                                </div>

  </td></tr>

  <j2:if test="$[empty(sysparm_task_survey)]">

  <j2:set var="jvar_task_survey_taken" value="false"/>

  </j2:if>

  <j2:if test="$[!empty(sysparm_task_survey)]">

  <g2:evaluate var="jvar_task_survey_taken" jelly="true">

  var ts = new GlideRecord("task_survey");

  if (!ts.isValid())

  "false";

  else {

  ts.addQuery("sys_id", jelly.sysparm_task_survey);

  ts.addQuery("state", "completed");

  ts.query();

  if (ts.hasNext())

  "true";

  else

  "false";

  }

  </g2:evaluate>

  </j2:if>

  <j2:if test="$[jvar_task_survey_taken]">

  <tr>

  <td colspan="2">

  ${gs.getMessage("This survey request has already been completed - thank you")}

  </td>

  </tr>

  </j2:if>

  <j2:if test="$[!jvar_task_survey_taken]">

  <tr>

  <td colspan="2">

                                                                              <g2:no_escape>

        $[NS:gr.introduction.getDisplayValue()]

                                                                              </g2:no_escape>

  </td>

  </tr>

  <g2:com.glideapp.survey_takesurvey survey="${sysparm_survey}" />

  <input name="sysparm_survey" type="HIDDEN" value="$[gr.sys_id]"/>

  <tr>

  <td height="20" ></td> <!-- spacer -->

  </tr>

  <tr>

  <td colspan="2">

  <input name="sys_action" type="HIDDEN" value="sysverb_post_survey"></input>

  <button class="listactions" type="submit" onClick="return onSubmit();" id="post_survey" name="post_survey" > ${gs.getMessage('Submit')} </button>

  </td>

  </tr>

  </j2:if>

                                                      </j2:if>

                                                      <j2:if test="$[jvar_redirect_to_login]">

                                                              <script>document.location.href = "survey_redirect.do?sysparm_survey_url=${sysparm_this_url}";</script>

                                                      </j2:if>

  </j2:if>

  </table>

  </form>

</j:jelly>

- Line 14 from above invokes the processor SurveyProcessor, which calls the SurveyProcessor() script include

var SurveyProcessor = Class.create();

SurveyProcessor.prototype = Object.extendsObject(AbstractScriptProcessor, {

  process : function() {

      try {

          var taskSurveyOn = gs.getProperty('glide.task.survey_active',false);

          var taskSurveyId = this._gsEscapeValue(this.request.getParameter('sysparm_task_survey'));

                                              //added to support assessments

          var taskAssessmentId = this._gsEscapeValue(this.request.getParameter('sysparm_task_assessment'));

                                              //addition July 2011 to support attaching doc_id & table_name to the survey response

          var documentTable = this._gsEscapeValue(this.request.getParameter('sysparm_document_table'));

          var documentId = this._gsEscapeValue(this.request.getParameter('sysparm_document_id'));

                                              //addition July 2011 to flag when the survey is weighted

          var weighted = this._gsEscapeValue(this.request.getParameter('sysparm_weighted'));

  var returnUrl = this._gsEscapeValue(this.request.getParameter('sysparm_return_url'));

          //make sure we at least have a survey parameter

          var survey = this._gsEscapeValue(this.request.getParameter('sysparm_survey'));

          if (!survey) {

              gs.log('Post Survey submitted without survey parameter');

              this.response.sendRedirect('home.do');

          }

          var user = this._gsEscapeValue(this.request.getParameter('sysparm_survey_user'));

          // in theory we could have passed a user out (which

          // we do if we email,

          // for example)

          // a sat survey to somebody

          // if they just took the survey from within the UI,

          // we can figure out

          // their UID from the session

          if (user == "")

              user = gs.getUserID();

          var update = this._gsEscapeValue(this.request.getParameter('sysparm_survey_update'));

          var bUpdate = false;

          if (update == "" || update == "true")

              bUpdate = true;

          //force instance update to false if using task survey feature

          if (taskSurveyOn == 'true' && taskSurveyId)

              bUpdate = false;

          // set up the survey instance

          var instance = this._getInstance(user, survey, bUpdate, documentTable, documentId);

         

          //update task survey table if feature is active

          if (taskSurveyOn == 'true' && taskSurveyId) {

              this._updateTaskSurvey(instance.getUniqueValue(), taskSurveyId, user);

          }

                                              //added to support assessments

          //update task_assessment table if this is an assessment

                                              //taskID used to return back to the correct task after submit is clicked

          if (taskAssessmentId) {

    gs.log("Instance: " + instance.getUniqueValue());

    gs.log("Task Assessment Id: " + taskAssessmentId);

    gs.log("User: " + user);

              var taskID = this._updateTaskAssessment(instance.getUniqueValue(), taskAssessmentId, user);

          }

         

          // now iterate the answers

          var response = new GlideRecord('survey_response');

                                              var score = "";

                                              var weight = "";

                                              var weightedScore = "";

          var en = this.request.getParameterNames();

          while (en.hasMoreElements()) {

              var arg = en.nextElement();

              if (arg.startsWith('QUESTION:')) {

          response.initialize();

                  var value = this.request.getParameter(arg);

                                                                              if (value == "")

                                                                                  value = "NULL";

                  var key = arg.substring('QUESTION:'.length);

                  var questiongr = new GlideRecord('survey_question_new');

                  if (!questiongr.get(key)) continue;

                                                                              //get the score for assessment response

                                                                             

                                                                              if (taskAssessmentId || weighted) {

                                                                                  var qGR = GlideRecord('assessment_question');

                                                                                  if(qGR.get(key)){

                                                                                      weight = qGR.weight || 1;

                                                                                  }

                                                                                  var aqGR = new GlideRecord('assessment_question_choice');

                                                                                  aqGR.addQuery('question', key);

                                                                                  aqGR.addQuery('value', value);

                                                                                  aqGR.query();

                                                                                  if(aqGR.next()){

                                                                                      score = aqGR.score;

                                                                                      weightedScore = weight * score;

                                                                                  }

                                                                              }

          //if question type is Multiple Choices or Select Box, populate the question_choice field

          var question_choice = "NULL";

          if(questiongr.getValue("type") == '3' || questiongr.getValue("type") == '5'){

              var qcGR = new GlideRecord('question_choice');

                          qcGR.addQuery('question', key);

                          qcGR.addQuery('value', value);

                          qcGR.query();

                          if(qcGR.next()){

                              question_choice = qcGR.getValue("sys_id");

                          }

          }

                  this._postResponse(response, instance.getUniqueValue(), key, value, bUpdate, weightedScore, question_choice);

              }

          }

  // A flag to indicate all the response records have been added/updated.

  instance.setValue("responses_received",'true');

  instance.update();

  if (returnUrl)

  this.response.sendRedirect(returnUrl);

  //added to support assessments so that the end not is not displayed as this is not necessary due to it

  //being in a dialog

  else if (taskAssessmentId) {

  this.response.sendRedirect('task.do?sys_id=' + taskID);

  } else {

  this.response.sendRedirect("survey_thanks.do?sysparm_survey=" + this._gsEscapeValue(this.request.getParameter('sysparm_survey')));

  }

      } catch (err) {

          gs.log("ERROR in SurveyProcessor: " + err.toString());

          this.response.sendRedirect('home.do');

      }

  },

  /**

    * Allow public access to this AJAX processor

    */

  isPublic: function() {

      return true;

  },

  _updateTaskSurvey : function(/*String*/ instance, /*String*/taskSurvey, /*String*/user) {

      var gr = new GlideRecord('task_survey');

      if (gr.get(taskSurvey)) {

          gr.setValue('instance', instance);

          gr.setDisplayValue('completed_date', gs.nowDateTime());

          gr.setValue('taken_by',user);

          gr.setValue('state', 'completed');

          gr.update();

      }

  },

              //added to support assessments

  _updateTaskAssessment : function(instance, taskAssessment, user) {

      var gr = new GlideRecord('task_assessment');

      if (gr.get(taskAssessment)) {

          gr.setValue('instance', instance);

          gr.setDisplayValue('completed_date', gs.nowDateTime());

          gr.setValue('completed_by', user);

                                              var taskID = gr.task;

          gr.update();

      }

              return taskID;

  },

 

 

  _getInstance : function(/*String*/user, /*String*/survey, /*boolean*/bUpdate, /**table**/doc_table, /**sys_id**/doc_id) {

      var gr = new GlideRecord('survey_instance');

      var doInsert = true;

      if (bUpdate) {

          gr.addQuery("taken_by", user);

          gr.addQuery("survey", survey);

                                              if (doc_table) {gr.addQuery("document_table", doc_table);}

                                              if (doc_id)       {gr.addQuery("document_id", doc_id);}

          gr.query();

          if (gr.next()) {

              doInsert = false;

                                                              gr.setValue('responses_received','false');

                                                              gr.update();

          }

      }

      if (doInsert) {

          gr.initialize();

          gr.setValue("taken_by", user);

          gr.setValue("survey", survey);

          gr.setValue("document_table", doc_table);

          gr.setValue("document_id", doc_id);

          gr.setDisplayValue("taken_on", gs.nowDateTime());

          gr.setValue("responses_received", 'false');

          gr.insert();

      }

                              return gr;

  },

  _gsEscapeValue : function(value)

  {

      if(value)

          return gs.escaper(value);

      else

          return value;

  },

  _postResponse : function(/*GlideRecord*/ response, /*String*/ instance, /*String*/ key, /*String*/ value, /*boolean*/ bUpdate, /*String*/ weightedScore, /*Sys_id*/ questionChoice) {

      var doInsert = true;

      if (bUpdate) {

          // try to update an existing response (if it exists)

          response.initialize();

          response.addQuery("instance", instance);

          response.addQuery("question", key);

          response.query();

          if (response.next()) {

              doInsert = false;

              response.setValue("response", value);

              response.setValue("answer_integer", weightedScore);

              response.setValue("question_choice", questionChoice);

              response.update();

          }

      }

      if (doInsert) {

          response.setValue("instance", instance);

          response.setValue("question", key);

          response.setValue("response", value);

          response.setValue("answer_integer", weightedScore);

          response.setValue("question_choice", questionChoice);

          response.insert();

      }

  },

 

  type : 'SurveyProcessor'

});

Line 154 - 165 from above populate the fields in the task_assessment table.

Having spent a fair bit of time trying to work out why this is breaking down (albeit infrequently), I am still at a loss, although I am thinking the issue lies from line 91 onwards in the 'Take Risk and Impact Assessment' UI Action script at the top of this page.

Any help or pointers would be greatly appreciated.

2 REPLIES 2

Michael Ritchie
ServiceNow Employee
ServiceNow Employee

I recently spent some time reusing this feature outside of change so I wanted to pass along some details that may help you troubleshoot it.   When you click on the 'Take Risk and Impact Assessment', the Ajax script include is creating a blank task_survey record and then passes it back to client so then present the blank assessment so the user can fill it out.   If they don't fill it out or don't click the Submit button then the task_survey record is supposed to be deleted automatically.   I am wondering if the ones you are seeing are ones there weren't deleted when they were supposed to be.


Arindam Ghosh
Mega Guru

Hi Daniel/Michael- I also got the same issues. But it is not happening   every time. Do you have any answer for this?



Thanks,


Arindam