Risk Assessment responses aren't always showing in Change Request related list
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 08:22 AM
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.
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.
- Labels:
-
Change Management
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-05-2017 09:38 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 08:06 AM
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