Name
sn_grc.GRCAssessmentUtilsBase
Description
No description available
Script
var GRCAssessmentUtilsBase = Class.create();
GRCAssessmentUtilsBase.DEFAULT_QUES_LIMIT = 250; //Default question limit for both grouped/consolidated assessment, in case if property is not found
GRCAssessmentUtilsBase.MAX_WIDTH = 50; //Maximum width of string, overflow will be represented by ...
GRCAssessmentUtilsBase.prototype = {
initialize: function() {},
evaluateAssessmentResult: function(current) {
return this._evaluateAssessmentResult(current);
},
getDefaultItemAssessment: function(item) {
return this._getDefaultItemAssessment(item);
},
cancelExistingAssessments: function(item) {
return this._cancelExistingAssessments(item);
},
/*
Supports below two group types -
grouped: This function creates a group of assessment instances so that user can take all the selected assessments using single UI page.
consolidate: This function creates a consolidated group of assessment instances so that user can take only one set of questions and after submit, answers will be copied over to all assessment instances contained in that consolidated group.
Metric type is default group by, it can be further group by sn_grc_item.content OR sn_grc_profile
*/
createGroup: function(ids, group_type, group_by) {
return this._groupAssessment(ids, group_type, group_by);
},
createGroupWS: function(ids, group_type, group_by) {
return this._groupAssessmentWS(ids, group_type, group_by);
},
removeFromGroup: function(instance) {
this._removeFromGroup(instance);
},
getGroupingPreview: function(ids, group_type, group_by) {
return this._getGroupingPreview(ids, group_type, group_by);
},
getGroupingPreviewWS: function(ids, group_type, group_by) {
return this._getGroupingPreviewWS(ids, group_type, group_by);
},
copyResponse: function(assessment) {
this._copyResponseToChildren(assessment);
},
_getEncodedQuery: function(type) {
var user = gs.getUserID();
var query = '';
switch (type) {
case 'attestation':
query = 'stateNOT INcomplete,canceled^metric_type.evaluation_method=attestation_v2^sn_grc_itemISNOTEMPTY';
break;
case 'risk':
query = 'stateNOT INcomplete,canceled^metric_type.evaluation_method=risk_assessment^sn_grc_itemISNOTEMPTY';
break;
case 'risk_advanced':
query = 'risk_identificationISNOTEMPTY^stateINready,wip';
break;
case 'tiering':
query = 'stateNOT INcomplete,canceled^metric_type.evaluation_method=vdr_risk_asmt^metric_type.classification=tiering_questionnaire_template';
break;
case 'all':
query = "stateNOT INcomplete,canceled^metric_type.evaluation_methodINattestation_v2,risk_assessment^sn_grc_itemISNOTEMPTY^userDYNAMIC" + user + "^NQrisk_identificationISNOTEMPTY^stateINready,wip^userDYNAMIC" + user;
break;
default:
query = 'stateNOT INcomplete,canceled^metric_type.evaluation_method=attestation_v2^sn_grc_itemISNOTEMPTY';
}
return query;
},
getAssessments: function(type) {
return this._getAssessments(type);
},
_getAssessments: function(type) {
var gr = new GlideRecord('asmt_assessment_instance');
gr.addQuery('user', gs.getUserID());
gr.addEncodedQuery(this._getEncodedQuery(type));
gr.orderByDesc('sys_created_on');
gr.query();
var list = [];
while (gr.next()) {
var asmt = {};
asmt.sys_id = gr.sys_id + '';
asmt.number = gr.number + '';
asmt.assigned_to = gr.getDisplayValue('user');
asmt.metric_type_id = gr.metric_type + '';
asmt.metric_type = gr.getDisplayValue('metric_type');
asmt.due_date = gr.due_date.getDisplayValue();
asmt.state = gr.getDisplayValue('state');
asmt.state_id = gr.state + '';
list.push(asmt);
}
return list;
},
getAssessmentsESC: function(type, startLimit, stopLimit, recList) {
return this._getAssessmentsESC(type, startLimit, stopLimit, recList);
},
_getAssessmentsESC: function(type, startLimit, stopLimit, prevList) {
var assessment = {};
var list = [];
var gr = new GlideRecord('asmt_assessment_instance');
gr.addQuery('user', gs.getUserID());
gr.addEncodedQuery(this._getEncodedQuery(type));
gr.chooseWindow(startLimit, stopLimit, false);
gr.orderBy('due_date');
gr.query();
function getField(gr, name) {
var f = {};
var id = gr.getUniqueValue();
gr = new GlideRecord(gr.getRecordClassName());
gr.get(id);
f.display_value = gr.getDisplayValue(name);
f.value = gr.getValue(name);
var ge = gr.getElement(name);
if (ge) {
var ed = ge.getED();
if (ed)
f.type = ed.getInternalType();
f.label = ge.getLabel();
}
return f;
}
function getProcessingActivity(entity) {
var pa = new GlideRecord("sn_privacy_processing_activity");
pa.addQuery('entity', entity);
pa.setLimit(1);
pa.query();
var f = {};
if (pa.hasNext()) {
pa.next();
f.display_value = pa.processing_activity_name + '';
f.value = pa.processing_activity_name + '';
}
return f;
}
//pushing previously cached data into list
if (prevList) {
for (var rec in prevList)
list.push(prevList[rec]);
}
var secondary_displays = '';
while (gr.next()) {
var asmt = {};
asmt.sys_id = gr.getUniqueValue();
asmt.number = gr.number + '';
asmt.assigned_to = gr.getDisplayValue('user');
asmt.metric_type_id = gr.metric_type + '';
asmt.metric_type = gr.getDisplayValue('metric_type');
asmt.due_date = gr.due_date.getDisplayValue();
asmt.state = gr.getDisplayValue('state');
asmt.state_id = gr.state + '';
if (type == "risk_advanced") {
var name = gs.getMessage("Risk identification questionnaire - {0}", [getField(gr, 'risk_identification').display_value]);
asmt.display_field = name;
} else {
secondary_displays = 'metric_type,sn_grc_profile';
asmt.display_field = getField(gr, 'sn_grc_item').display_value;
}
asmt.secondary_displays = [];
if (secondary_displays) {
secondary_displays.split(",").forEach(function(sDisplay) {
asmt.secondary_displays.push(getField(gr, sDisplay));
});
}
list.push(asmt);
}
assessment.list = list;
return assessment;
},
getGRCAssessmentCount: function(type, isOverdue) {
return this._getAssessmentsCount(type, isOverdue);
},
_getAssessmentsCount: function(type, isOverdue) {
var gr = new GlideRecord('asmt_assessment_instance');
if (type != 'all')
gr.addQuery('user', gs.getUserID());
gr.addEncodedQuery(this._getEncodedQuery(type));
if (isOverdue)
gr.addQuery('due_date', '<', new GlideDateTime());
gr.query();
return gr.getRowCount();
},
assessItem: function(item) {
var group = '';
if (!item || !item.attestation || !item.respondents)
return;
if (!this._verifyItemSetup(item))
return;
var respondents = item.respondents.split(',');
var total = 0;
for (var i = 0; i < respondents.length; i++) {
var result = new global.AssessmentUtils().createAssessments(item.attestation + '', item.sys_id + '', respondents[i], '');
result = result.split(',');
if (result.length >= 3) {
if (i == 0)
group = result[0];
total++;
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.setValue('assessment', result[0]);
gr.setValue('item', item.sys_id);
gr.setValue('group', group);
gr.insert();
gr = new GlideRecord('asmt_assessment_instance');
gr.get(result[0]);
gr.setValue('sn_grc_profile', item.profile.sys_id);
gr.setValue('sn_grc_item', item.sys_id);
gr.update();
}
}
return total;
},
closeAllIssues: function(control, msg) {
this._closeAllIssues(control, msg);
},
calculateQuestionsAnswered: function(instance) {
return this._calculateQuestionsAnswered(instance);
},
_removeFromGroup: function(instance) {
if (!instance || !instance.sn_grc_parent || !instance.sn_grc_item || instance.sn_grc_status != 'no_action')
return;
if (instance.sn_grc_parent.state == 'complete' || instance.sn_grc_parent.state == 'canceled') {
gs.addErrorMessage(gs.getMessage("Cannot remove {0} because the group is in {1} state.", [instance.getDisplayValue(), instance.sn_grc_parent.state.getDisplayValue().toLowerCase()]));
return;
}
var type = instance.sn_grc_parent.sn_grc_group_type;
var questionGA = new GlideAggregate('asmt_assessment_instance_question');
if (type == 'consolidated')
questionGA.addQuery('instance.sn_grc_parent', instance.sn_grc_parent);
else
questionGA.addQuery('instance', instance.sn_grc_parent);
questionGA.addAggregate('COUNT', 'source_id');
questionGA.query();
if (questionGA.getRowCount() <= 2) {
var parent = new GlideRecord('asmt_assessment_instance');
if (parent.get(instance.sn_grc_parent + '')) {
gs.addInfoMessage(gs.getMessage('{0} has been successfully removed from the group. {1} group will be removed because it contains less than 2 assessments.', [instance.number, parent.number]));
new global.AssessmentUtils().deleteInstance(parent);
}
} else {
if (type == 'grouped') {
var question = new GlideRecord('asmt_assessment_instance_question');
question.addQuery('instance', instance.sn_grc_parent);
question.addQuery('source_id', instance.sn_grc_item);
question.deleteMultiple();
}
// ungroup current record, update parent as empty.
var assessmentInstance = new GlideRecord('asmt_assessment_instance');
assessmentInstance.get(instance.getUniqueValue());
assessmentInstance.setValue('sn_grc_parent', '');
assessmentInstance.update();
gs.addInfoMessage(gs.getMessage('{0} has been successfully removed from the group.', instance.number));
}
},
_getGroupingPreview: function(ids, type, group_by) {
if (!ids || !type || (type != 'grouped' && type != 'consolidated'))
return;
var i = 0;
var group_count = 0;
var error_msg = '';
var error_msg_limit = '';
var nonQualifiedIns = [];
var preview = [];
var preview_msg = '';
var url = '';
var invalidLink = '';
var ques_limit = parseInt(gs.getProperty('sn_grc.' + type + '_questions_limit', GRCAssessmentUtilsBase.DEFAULT_QUES_LIMIT));
var asmtIns = new GlideRecord('asmt_assessment_instance');
var asmt = this._getValidAsmtIns(ids);
var lessSelectedError = asmt.getRowCount() <= 1;
var limitExceededError = false;
var map = this._getAsmtGroupMap(asmt, group_by);
for (var group_id in map) {
var ques_count = 0;
if (map[group_id].length <= 1) {
lessSelectedError = true;
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].number);
continue;
}
if (asmtIns.get(map[group_id][0].sys_id))
ques_count = this._getQuestionsCount(asmtIns) * map[group_id].length;
if (ques_count <= 0 || ques_count > ques_limit) {
limitExceededError = true;
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].number);
continue;
}
group_count++;
asmt_numbers = map[group_id].map(function(asmt) {
return asmt.number;
}).join(',');
var asmtTxt = gs.getMessage('{0} assessments', [map[group_id].length + '']);
var previewMsgAriaTxt = gs.getMessage('Group {0}, {1} has {2} assessments. Click to view assessments.', [group_count + '', map[group_id][0].group_name, map[group_id].length + '']);
var preview_url = '/asmt_assessment_instance_list.do?sysparm_query=' + encodeURIComponent('numberIN' + asmt_numbers) + '&sysparm_view=GRC_Attestation&sysparm_stack=no';
var preview_link = '<a aria-label="' + previewMsgAriaTxt + '" href="' + preview_url + '" target="_blank">' + asmtTxt + '</a>';
var previewMsgTxt = gs.getMessage('Group {0}: {1} ({2})', [group_count + '', map[group_id][0].group_name, preview_link]);
preview_msg += '<li>' + previewMsgTxt + '</li>';
}
if (lessSelectedError && group_count > 0)
error_msg = gs.getMessage('Some groups cannot be created based on the current \'group by\' criteria. Check preview for more details.');
else if (lessSelectedError)
error_msg = gs.getMessage('No groups will be created based on the current \'group by\' criteria. Check preview for more details.');
if (limitExceededError)
error_msg_limit = gs.getMessage('Limit of {0} questions exceeded. Please select fewer number of assessments or change the \'group by\' criteria. Check preview for more details.', [ques_limit + '']);
var stats = '<h5>';
stats += gs.getMessage('{0} groups will be created', [group_count + '']);
if (group_count > 0)
stats += ':</h5><div><ul>' + preview_msg + '</ul></div>';
else
stats += '.</h5>';
if (nonQualifiedIns.length > 0) {
url = '/asmt_assessment_instance_list.do?sysparm_query=' + encodeURIComponent('numberIN' + nonQualifiedIns.join(',')) + '&sysparm_view=GRC_Attestation&sysparm_stack=no';
previewMsgTxt = gs.getMessage('{0} selected assessments', [nonQualifiedIns.length + '']);
previewMsgAriaTxt = gs.getMessage('{0} selected assessments will not be grouped. Click to view assessments.', [nonQualifiedIns.length + '']);
invalidLink = '<a aria-label="' + previewMsgAriaTxt + '" href="' + url + '" target="_blank">' + previewMsgTxt + '</a>';
stats += gs.getMessage('{0} will not be grouped.', [invalidLink]);
}
return {
stats: stats,
error_msg: error_msg,
error_msg_limit: error_msg_limit,
group_count: group_count,
};
},
_getGroupingPreviewWS: function(ids, type, group_by) {
if (!ids || !type || (type != 'grouped' && type != 'consolidated'))
return;
var i = 0;
var group_count = 0;
var error_msg = '';
var error_msg_limit = '';
var nonQualifiedIns = [];
var preview = [];
var preview_groups = [];
var url_ws = '';
var asmt_sysIds = '';
var invalidLink = '';
var invalid_msg = {};
var ques_limit = parseInt(gs.getProperty('sn_grc.' + type + '_questions_limit', GRCAssessmentUtilsBase.DEFAULT_QUES_LIMIT));
var asmtIns = new GlideRecord('asmt_assessment_instance');
var asmt = this._getValidAsmtInsWS(ids);
var lessSelectedError = asmt.getRowCount() <= 1;
var limitExceededError = false;
var map = this._getAsmtGroupMapWS(asmt, group_by);
for (var group_id in map) {
var ques_count = 0;
if (map[group_id].length <= 1) {
lessSelectedError = true;
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].sys_id);
continue;
}
if (asmtIns.get(map[group_id][0].sys_id))
ques_count = this._getQuestionsCount(asmtIns) * map[group_id].length;
if (ques_count <= 0 || ques_count > ques_limit) {
limitExceededError = true;
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].sys_id);
continue;
}
group_count++;
asmt_sysIds = map[group_id].map(function(asmt) {
return asmt.sys_id;
}).join(',');
var asmtTxt = gs.getMessage('{0} assessments', [map[group_id].length + '']);
var previewMsgAriaTxt = gs.getMessage('Group {0}, {1} has {2} assessments. Click to view assessments.', [group_count + '', map[group_id][0].group_name, map[group_id].length + '']);
var preview_url_ws = 'now/risk/common/list-view/asmt_assessment_instance/params/query/sys_idIN' + asmt_sysIds + '/list-title/Assessments';
var preview_msg = {};
preview_msg.group_count = gs.getMessage('Group {0}', group_count.toString());
preview_msg.metric_type = map[group_id][0].group_name.split(' #~# ')[0];
if (map[group_id][0].group_name.split(' #~# ').length > 1)
preview_msg.group_by = map[group_id][0].group_name.split(' #~# ')[1];
preview_msg.preview_link = asmtTxt;
preview_msg.preview_url_ws = preview_url_ws;
preview_groups.push(preview_msg);
}
var invalidAsmtsPreview = this._getInvalidAsmtInsPreviewWS(ids);
while (invalidAsmtsPreview.next()) {
nonQualifiedIns.push(invalidAsmtsPreview.getUniqueValue());
}
if (lessSelectedError && group_count > 0)
error_msg = gs.getMessage('Some groups cannot be created based on the current \'group by\' criteria. Check preview for more details.');
else if (lessSelectedError)
error_msg = gs.getMessage('No groups will be created based on the current \'group by\' criteria. Check preview for more details.');
if (limitExceededError)
error_msg_limit = gs.getMessage('Limit of {0} questions exceeded. Try changing the grouping options or select fewer assessments.', [ques_limit + '']);
if (nonQualifiedIns.length > 0) {
url_ws = 'now/risk/common/list-view/asmt_assessment_instance/params/query/sys_idIN' + nonQualifiedIns.join(',') + '/list-title/Assessments';
invalid_msg.url_ws = url_ws;
invalid_msg.link = gs.getMessage("View assessments");
invalid_msg.text = gs.getMessage('{0} assessments can\'t be grouped. ', [nonQualifiedIns.length + '']);
}
var result = {
preview_groups: preview_groups,
invalid_msg: invalid_msg,
error_msg: error_msg,
error_msg_limit: error_msg_limit,
group_count: group_count,
};
return result;
},
_groupAssessment: function(ids, type, group_by) {
if (!ids || !type || (type != 'grouped' && type != 'consolidated'))
return;
var i = 0;
var url = '';
var invalidLink = '';
var msgs = {
info: '',
error: ''
};
var success = false;
var parentIns = [];
var nonQualifiedIns = [];
var asmtNumbers = '';
var ques_limit = parseInt(gs.getProperty('sn_grc.' + type + '_questions_limit', GRCAssessmentUtilsBase.DEFAULT_QUES_LIMIT));
var asmtIns = new GlideRecord('asmt_assessment_instance');
var asmt = this._getValidAsmtIns(ids);
if (asmt.getRowCount() != ids.split(',').length) {
var invalidAsmt = this._getInvalidAsmtIns(ids);
while (invalidAsmt.next())
nonQualifiedIns.push(invalidAsmt.getValue('number'));
url = '/asmt_assessment_instance_list.do?sysparm_query=' + encodeURIComponent('numberIN' + nonQualifiedIns.join(',')) + '&sysparm_view=GRC_Attestation&sysparm_stack=no';
invalidLink = '<a href="' + url + '" target="_blank">' + nonQualifiedIns.length + '</a>';
msgs.error = gs.getMessage('Assessments could not be grouped due to a change in status in {0} of the assessments. Please refresh the assessments list and try again.', [invalidLink]);
return {
msgs: msgs,
success: success
};
}
var map = this._getAsmtGroupMap(asmt, group_by);
for (var group_id in map) {
var ques_count = 0;
var sources = '';
var metric_type = group_id.split('^')[0];
if (map[group_id].length <= 1)
continue;
if (asmtIns.get(map[group_id][0].sys_id))
ques_count = this._getQuestionsCount(asmtIns) * map[group_id].length;
if (ques_count <= 0 || ques_count > ques_limit)
continue;
if (type == 'consolidated')
sources = map[group_id][0].sn_grc_item;
else if (type == 'grouped')
sources = map[group_id].map(function(asmt) {
return asmt.sn_grc_item;
}).join(',');
var result = new global.AssessmentUtils().createAssessments(metric_type + '', sources + '', gs.getUserID(), '');
if (result.length >= 3) {
var parent = result.split(',')[0];
if (asmtIns.get(parent)) {
success = true;
parentIns.push(this._asmtInstanceToJson(asmtIns));
var childAsmtSysIds = map[group_id].map(function(asmt) {
return asmt.sys_id;
}).join(',');
this._updateParent(childAsmtSysIds, parent, metric_type, type);
} else
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].number);
} else
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].number);
}
if (nonQualifiedIns.length > 0) {
url = '/asmt_assessment_instance_list.do?sysparm_query=' + encodeURIComponent('numberIN' + nonQualifiedIns.join(',')) + '&sysparm_view=GRC_Attestation&sysparm_stack=no';
invalidLink = '<a href="' + url + '" target="_blank"><b>' + nonQualifiedIns.length + '</b></a>';
msgs.error = gs.getMessage('Cannot create the assessment group for {0} selected assessments.', [invalidLink]);
}
var links = [];
for (i = 0; i < parentIns.length; i++) {
url = '/asmt_assessment_instance.do?sysparm_query=' + encodeURIComponent('sys_id=' + parentIns[i].sys_id) + '&sysparm_view=GRC_Attestation&sysparm_stack=no';
var link = '<a href="' + url + '" target="_blank">' + parentIns[i].number + '</a>';
links.push(link);
}
if (parentIns.length == 1)
msgs.info = gs.getMessage('Assessment group {0} has been created.', [links.join(', ')]);
else if (parentIns.length > 1)
msgs.info = gs.getMessage('Assessment groups {0} have been created.', [links.join(', ')]);
return {
msgs: msgs,
success: success
};
},
_groupAssessmentWS: function(ids, type, group_by) {
if (!ids || !type || (type != 'grouped' && type != 'consolidated'))
return;
var i = 0;
var url = '';
var url_ws = '';
var msgs = {
info: '',
infoLink: '',
infoUrl: '',
error: '',
errorLink: '',
errorUrl: ''
};
var groupedAsmtSysIds = [];
var status = "Error";
var parentIns = [];
var nonQualifiedIns = [];
var asmtNumbers = '';
var ques_limit = parseInt(gs.getProperty('sn_grc.' + type + '_questions_limit', GRCAssessmentUtilsBase.DEFAULT_QUES_LIMIT));
var asmtIns = new GlideRecord('asmt_assessment_instance');
var asmt = this._getValidAsmtInsWS(ids);
if (asmt.getRowCount() != ids.split(',').length) {
var invalidAsmt = this._getInvalidAsmtInsWS(ids);
while (invalidAsmt.next())
nonQualifiedIns.push(invalidAsmt.getUniqueValue());
if (nonQualifiedIns.length > 0) {
url_ws = 'now/risk/common/list-view/asmt_assessment_instance/params/query/sys_idIN' + nonQualifiedIns.join(',') + '/list-title/Assessments';
msgs.error = gs.getMessage('Grouping unsuccessful. {0} assessments have already been completed or canceled and cannot be grouped. ', nonQualifiedIns.length + '');
msgs.errorLink = gs.getMessage("View assessments");
msgs.errorUrl = url_ws;
return {
msgs: msgs,
status: status
};
}
}
var map = this._getAsmtGroupMapWS(asmt, group_by);
for (var group_id in map) {
var ques_count = 0;
var sources = '';
var metric_type = group_id.split('^')[0];
if (map[group_id].length <= 1)
continue;
if (asmtIns.get(map[group_id][0].sys_id))
ques_count = this._getQuestionsCount(asmtIns) * map[group_id].length;
if (ques_count <= 0 || ques_count > ques_limit)
continue;
if (type == 'consolidated')
sources = map[group_id][0].sn_grc_item;
else if (type == 'grouped')
sources = map[group_id].map(function(asmt) {
return asmt.sn_grc_item;
}).join(',');
var result = new global.AssessmentUtils().createAssessments(metric_type + '', sources + '', gs.getUserID(), '');
if (result.length >= 3) {
var parent = result.split(',')[0];
if (asmtIns.get(parent)) {
status = "Success";
parentIns.push(this._asmtInstanceToJson(asmtIns));
groupedAsmtSysIds.push(parent);
var childAsmtSysIds = map[group_id].map(function(asmt) {
return asmt.sys_id;
}).join(',');
this._updateParent(childAsmtSysIds, parent, metric_type, type);
} else
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].sys_id);
} else
for (i = 0; i < map[group_id].length; i++)
nonQualifiedIns.push(map[group_id][i].sys_id);
}
var invalid_url_ws;
if (nonQualifiedIns.length > 0) {
invalid_url_ws = 'now/risk/common/list-view/asmt_assessment_instance/params/query/sys_idIN' + nonQualifiedIns.join(',') + '/list-title/Assessments';
msgs.error = gs.getMessage('Grouping unsuccessful for {0} assessments. ', nonQualifiedIns.length + '');
msgs.errorLink = gs.getMessage("View assessments");
msgs.errorUrl = invalid_url_ws;
}
var links = [];
var infoLink;
var groupedAssessmentsListUrl = 'now/risk/common/list-view/asmt_assessment_instance/params/query/sys_idIN' + groupedAsmtSysIds.join(',') + '/list-title/Grouped assessments';
if (parentIns.length == 1) {
msgs.info = gs.getMessage('1 assessment group created. ');
msgs.infoLink = gs.getMessage('View group');
} else if (parentIns.length > 1) {
msgs.info = gs.getMessage('{0} assessment groups created. ', parentIns.length + '');
msgs.infoLink = gs.getMessage('View groups');
}
msgs.infoUrl = groupedAssessmentsListUrl;
return {
msgs: msgs,
status: status,
};
},
_getStringWithinMaxWidth: function(name) {
var str = '';
if (name.length > GRCAssessmentUtilsBase.MAX_WIDTH)
str = name.substring(0, GRCAssessmentUtilsBase.MAX_WIDTH) + '...';
else
str = name;
return str;
},
_getAsmtGroupMap: function(asmt, group_by) {
var map = {};
if (!asmt)
return map;
while (asmt.next()) {
var group_by_name = '';
if (group_by) {
var elem = asmt.getElement(group_by);
if (elem && elem.getDisplayValue())
group_by_name = ' - ' + this._getStringWithinMaxWidth(elem.getDisplayValue());
}
var groupId = asmt.metric_type + (!group_by ? '' : '^' + elem);
if (!map[groupId])
map[groupId] = [];
var metric_type = this._getStringWithinMaxWidth(asmt.metric_type.getDisplayValue());
var group_name = metric_type + group_by_name;
map[groupId].push(this._asmtInstanceToJson(asmt, group_name));
}
return map;
},
_getAsmtGroupMapWS: function(asmt, group_by) {
var map = {};
if (!asmt)
return map;
while (asmt.next()) {
var group_by_name = '';
if (group_by) {
var elem = asmt.getElement(group_by);
if (elem && elem.getDisplayValue())
group_by_name = ' #~# ' + this._getStringWithinMaxWidth(elem.getDisplayValue());
}
var groupId = asmt.metric_type + (!group_by ? '' : '^' + elem);
if (!map[groupId])
map[groupId] = [];
var metric_type = this._getStringWithinMaxWidth(asmt.metric_type.getDisplayValue());
var group_name = metric_type + group_by_name;
map[groupId].push(this._asmtInstanceToJson(asmt, group_name));
}
return map;
},
_getValidAsmtIns: function(ids) {
if (!ids)
return;
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addQuery('state', 'NOT IN', 'complete,canceled');
asmt.addQuery('user', gs.getUserID());
asmt.addNullQuery('sn_grc_parent');
asmt.addNotNullQuery('sn_grc_item');
asmt.addNotNullQuery('sn_grc_profile');
asmt.query();
return asmt;
},
_getValidAsmtInsWS: function(ids) {
if (!ids)
return;
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addQuery('state', 'NOT IN', 'complete,canceled');
asmt.addQuery('metric_type.evaluation_method', 'attestation_v2');
asmt.addQuery('user', gs.getUserID());
asmt.addNullQuery('sn_grc_parent');
asmt.addNotNullQuery('sn_grc_item');
asmt.addNotNullQuery('sn_grc_profile');
asmt.query();
return asmt;
},
_getInvalidAsmtIns: function(ids) {
if (!ids)
return;
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addEncodedQuery('stateINcomplete,canceled^ORsn_grc_parentISNOTEMPTY');
asmt.addQuery('user', gs.getUserID());
asmt.addNotNullQuery('sn_grc_item');
asmt.addNotNullQuery('sn_grc_profile');
asmt.query();
return asmt;
},
_getInvalidAsmtInsWS: function(ids) {
if (!ids)
return;
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addEncodedQuery('stateINcomplete,canceled^ORsn_grc_parentISNOTEMPTY');
asmt.addQuery('metric_type.evaluation_method', 'attestation_v2');
asmt.addQuery('user', gs.getUserID());
asmt.addNotNullQuery('sn_grc_item');
asmt.addNotNullQuery('sn_grc_profile');
asmt.query();
return asmt;
},
_getInvalidAsmtInsPreviewWS: function(ids) {
if (!ids)
return;
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addQuery('state', 'IN', 'complete,canceled')
.addOrCondition('sn_grc_parent', '!=', '')
.addOrCondition('sn_grc_item', '')
.addOrCondition('sn_grc_profile', '')
.addOrCondition('metric_type.evaluation_method', '!=', 'attestation_v2')
.addCondition('user', '!=', gs.getUserID());
asmt.query();
return asmt;
},
_asmtInstanceToJson: function(gr, group_name) {
if (!gr)
return;
var obj = {};
var col = ['sys_id', 'metric_type', 'sn_grc_item', 'number'];
for (var i = 0; i < col.length; i++)
if (gr[col[i]])
obj[col[i]] = gr.getValue(col[i]);
if (group_name)
obj['group_name'] = group_name;
return obj;
},
_getQuestionsCount: function(asmt) {
var ga = new GlideAggregate('asmt_assessment_instance_question');
ga.addQuery('instance', asmt.getUniqueValue());
ga.addAggregate('COUNT(DISTINCT', 'metric.sys_id');
ga.groupBy('category');
ga.query();
if (ga.next())
return ga.getRowCount() * ga.getAggregate('COUNT(DISTINCT', 'metric.sys_id');
return 0;
},
_updateParent: function(ids, parent, metric_type, group_type) {
var asmt = new GlideRecord('asmt_assessment_instance');
asmt.addQuery('sys_id', 'IN', ids);
asmt.addQuery('user', gs.getUserID());
asmt.addQuery('state', 'NOT IN', 'complete,canceled');
asmt.addQuery('metric_type', metric_type);
asmt.setValue('sn_grc_parent', parent);
asmt.updateMultiple();
var dueDate = this._getDate(parent);
asmt.initialize();
asmt.get(parent);
asmt.setValue('sn_grc_group_type', group_type);
if (dueDate)
asmt.setValue('due_date', dueDate);
asmt.update();
if (group_type == 'consolidated')
this._adjustSource(metric_type, asmt);
},
_getDate: function(parent) {
if (!parent)
return;
var child = new GlideRecord('asmt_assessment_instance');
child.addQuery('sn_grc_parent', parent);
child.orderByDesc('due_date');
child.setLimit(1);
child.query();
if (child.next())
return child.getValue('due_date');
},
_adjustSource: function(metric_type, parent) {
var link_text = gs.getMessage('here');
var link = "<a href='/asmt_assessment_instance.do?sys_id=" + parent.getUniqueValue() + "&sysparm_view=GRC_Attestation&sysparm_stack=no' target='_blank'>" + link_text + "</a>";
var mgt = new GlideRecord('asmt_metric_type_group');
mgt.name = gs.getMessage('Provide one response for all assessments');
mgt.description = gs.getMessage('Click {0} to access the assessment group instance to review all related controls/risks.', [link]);
mgt.metric_type = metric_type;
var grp = mgt.insert();
var quesInstance = new GlideRecord('asmt_assessment_instance_question');
quesInstance.addQuery('instance', parent.getUniqueValue());
quesInstance.setValue('source_table', 'asmt_assessment_instance');
quesInstance.setValue('source_id', parent.getUniqueValue());
quesInstance.setValue('metric_type_group', grp);
quesInstance.updateMultiple();
},
_closeAllIssues: function(control, msg) {
var issuesToItemM2M = new GlideRecord("sn_grc_m2m_issue_item");
issuesToItemM2M.addQuery("sn_grc_item", control.getUniqueValue());
issuesToItemM2M.addQuery('sn_grc_issue.active=true');
issuesToItemM2M.query();
var issueRec = new GlideRecord("sn_grc_issue");
while (issuesToItemM2M.next()) {
issueRec.initialize();
if (issueRec.get(issuesToItemM2M.getValue('sn_grc_issue'))) {
issueRec.setValue('response', '1');
issueRec.setValue('explanation', msg);
issueRec.setValue('state', '3'); //closed complete
issueRec.update();
}
}
},
_cancelExistingAssessments: function(item) {
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.addQuery('item', item.sys_id + '');
gr.addEncodedQuery('assessment.stateNOT INcomplete,canceled');
gr.query();
var total = gr.getRowCount();
while (gr.next()) {
this._cancelAssessment(gr.assessment + '');
var instance = new GlideRecord('asmt_assessment_instance');
instance.get(gr.assessment);
this._removeFromGroup(instance);
}
return total;
},
_cancelAssessment: function(assessmentId) {
var gr = new GlideRecord('asmt_assessment_instance');
gr.get(assessmentId);
gr.setValue('state', 'canceled');
gr.update();
},
_getPropertyName: function(item) {
var propertyName = '';
var table = item.getTableName();
if ((table == 'sn_compliance_control') || (table == 'sn_compliance_policy_statement'))
propertyName = 'sn_compliance.default_attestation';
else if ((table == 'sn_risk_risk') || (table == 'sn_risk_definition'))
propertyName = 'sn_risk.default_assessment';
return propertyName;
},
_getItemAssessment: function(item) {
if (item && item.attestation != '')
return item.attestation + '';
else
return;
},
_getDefaultItemAssessment: function(item) {
var propertyName = this._getPropertyName(item);
var assessmentProperty = new GlideRecord('sys_properties');
assessmentProperty.get('name', propertyName);
var assessment = new GlideRecord('asmt_metric_type');
if (assessment.get('name', assessmentProperty.value + ''))
return assessment.sys_id + '';
return '';
},
_verifyItemSetup: function(item) {
var assessableRecord = this._getAssessableRecord(item);
if (assessableRecord) {
this._checkItemInGroup(item, assessableRecord);
return true;
}
return false;
},
_getAssessableRecord: function(item) {
var metricType = this._getItemAssessment(item);
var sourceTable = item.sys_class_name + '';
var assessableRecord = new GlideRecord('asmt_assessable_record');
assessableRecord.addQuery('source_id', item.sys_id + '');
assessableRecord.addQuery('source_table', sourceTable);
assessableRecord.addQuery('metric_type', metricType);
assessableRecord.query();
if (assessableRecord.next())
return assessableRecord;
return null;
},
_checkItemInGroup: function(item, assessableRecord) {
var itemTable = item.sys_class_name + '';
var itemIds = [];
var otherItem = new GlideRecord(itemTable);
otherItem.addQuery('profile', item.profile);
otherItem.addQuery('sys_id', '!=', item.sys_id);
otherItem.query();
while (otherItem.next())
itemIds.push(otherItem.sys_id + '');
var otherAssessable = new GlideRecord('asmt_assessable_record');
otherAssessable.addQuery('metric_type', assessableRecord.metric_type);
otherAssessable.addQuery('source_id', 'IN', itemIds);
otherAssessable.addQuery('metric_type_group', 'ISNOTEMPTY', '');
otherAssessable.setLimit(1);
otherAssessable.query();
if (otherAssessable.next())
assessableRecord.metric_type_group = otherAssessable.metric_type_group;
else
assessableRecord.metric_type_group = this._createMetricTypeGroup(item, assessableRecord.metric_type);
assessableRecord.update();
},
_createMetricTypeGroup: function(item, metricType) {
var mgt = new GlideRecord('asmt_metric_type_group');
var profile = new sn_grc.GRCUtils().getMessage('profile');
mgt.name = gs.getMessage('{1}: {0}', [item.profile.name, profile]);
mgt.metric_type = metricType;
return mgt.insert();
},
_allAssessmentsFinished: function(assessmentId) {
// Check if all recipients complete the assessments
var item = this._getItemByAssessment(assessmentId);
if (!item)
return false;
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.addQuery('item', item.sys_id + '');
gr.addEncodedQuery('assessment.stateNOT INcomplete,canceled');
gr.query();
if (gr.getRowCount() > 0)
return false;
return true;
},
_getItemByAssessment: function(assessmentId) {
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.addQuery('assessment', assessmentId);
gr.setLimit(1);
gr.query();
if (gr.next())
return gr.item;
else
return null;
},
_createAttestationIssue: function(control) {
var issueUtils = new sn_grc.IssueUtils();
issueUtils.updateOrCreateAttestationIssue(control);
},
_closeAttestationIssue: function(control) {
new sn_grc.IssueUtils().removeSourceOrCloseAttestationIssue(control);
},
_controlHasIssues: function(control) {
return new sn_grc.IssueUtils().itemHasOpenIssues(control.sys_id);
},
_evaluateControl: function(itemId, group) {
var control = new GlideRecord('sn_compliance_control');
if (!control.get(itemId))
return;
if (control.exempt) {
control.state = 'review';
control.update();
return;
}
var allAssessments = [];
// Get all assessments that need to be assessed
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.addQuery('item', itemId);
gr.addQuery('group', group);
gr.query();
while (gr.next())
allAssessments.push(gr.assessment + '');
var compliance = 'compliant';
var assessInstanceQ = new GlideRecord("asmt_assessment_instance_question");
var qc = assessInstanceQ.addQuery('instance', allAssessments[0]);
for (var m = 1; m < allAssessments.length; m++) {
qc.addOrCondition('instance', allAssessments[m]);
}
assessInstanceQ.addQuery('metric.scored', 'true');
assessInstanceQ.addQuery('is_hidden', 'false');
assessInstanceQ.orderBy('source_id');
assessInstanceQ.query();
// these date type are not scored: 1 Multiple Selection 2 Attachment 3 Date 4 DateTime 5 Reference 6 String 7 Ranking
while (assessInstanceQ.next()) {
var value = assessInstanceQ.value + '';
var correctAnswer = '';
var type = assessInstanceQ.metric.datatype + '';
var sysIds = '';
var defId = '';
var isWrongAnswer = false;
switch (type) {
case "boolean":
correctAnswer = assessInstanceQ.metric.correct_answer_yesno + '';
isWrongAnswer = (value != correctAnswer);
break;
case "checkbox":
correctAnswer = assessInstanceQ.metric.correct_answer_checkbox + '';
isWrongAnswer = (value != correctAnswer);
break;
case "template":
defId = this._getMetricTemplateDefinitionId(assessInstanceQ.metric + '', value);
sysIds = assessInstanceQ.metric.correct_answer_template + '';
isWrongAnswer = (sysIds.indexOf(defId) < 0);
break;
case "choice":
case "numericscale":
case "imagescale":
case "scale":
defId = this._getMetricDefinitionId(assessInstanceQ.metric + '', value);
sysIds = assessInstanceQ.metric.correct_answer_choice + '';
isWrongAnswer = (sysIds.indexOf(defId) < 0);
break;
case "duration":
case "percentage":
case "long":
correctAnswer = assessInstanceQ.metric.correct_answer + '';
isWrongAnswer = (value != correctAnswer);
break;
default:
correctAnswer = assessInstanceQ.metric.correct_answer + '';
isWrongAnswer = (value != correctAnswer);
}
if (value != -1 && isWrongAnswer) // value is incorrect
compliance = 'non_compliant';
else if (value == -1 && compliance == 'compliant') // value is n/a and rest of the metric values are compliant
compliance = 'not_applicable';
}
if (compliance == 'non_compliant')
this._createAttestationIssue(control);
else if (compliance == 'compliant') {
this._closeAttestationIssue(control);
if (this._controlHasIssues(control)) {
//If the control still has other issues, mark it as
//non-compliant
compliance = 'non_compliant';
}
} else if (compliance == 'not_applicable')
this._closeAttestationIssue(control);
control = new GlideRecord('sn_compliance_control');
control.get(itemId);
control.state = 'review';
control.status = compliance;
control.update();
},
_getMetricTemplateDefinitionId: function(metric, value) {
var m = new GlideRecord('asmt_metric');
if ((!m.get(metric)) || (!m.getValue('template')))
return '';
var gr = new GlideRecord('asmt_template_definition');
gr.addQuery('template', m.template + '');
gr.addQuery('value', value);
gr.query();
if (gr.next())
return gr.getUniqueValue() + '';
return '';
},
_getMetricDefinitionId: function(metric, value) {
var gr = new GlideRecord('asmt_metric_definition');
gr.addQuery('metric', metric);
gr.addQuery('value', value);
gr.query();
if (gr.next())
return gr.getUniqueValue() + '';
return '';
},
_evaluateRisk: function(itemId) {
var risk = new GlideRecord('sn_risk_risk');
if (risk.get(itemId)) {
risk.state = 'respond';
risk.update();
}
},
_getGroupForAssessment: function(itemId, assessmentId) {
var group = '';
var gr = new GlideRecord('sn_grc_m2m_item_assessment');
gr.addQuery('item', itemId);
gr.addQuery('assessment', assessmentId);
gr.query();
if (gr.next())
group = gr.group + '';
return group;
},
_evaluateAssessmentResult: function(assessment) {
var assessmentId = assessment.sys_id + '';
var group = '';
if (assessment.sn_grc_parent && assessment.sn_grc_parent.state != 'complete' && assessment.sn_grc_parent.state != 'canceled' && assessment.sn_grc_status == 'no_action')
this._removeFromGroup(assessment);
if (!this._allAssessmentsFinished(assessmentId))
return;
var item = this._getItemByAssessment(assessmentId);
if (!item)
return;
var itemId = item.sys_id + '';
group = this._getGroupForAssessment(itemId, assessmentId);
var sourceTable = item.sys_class_name + '';
if (sourceTable == 'sn_risk_risk')
this._evaluateRisk(itemId);
else if (sourceTable == 'sn_compliance_control')
this._evaluateControl(itemId, group);
},
_copyResponseToChildren: function(assessment) {
if (!assessment || assessment.sn_grc_group_type.nil() || !assessment.sn_grc_parent.nil() || !assessment.sn_grc_item.nil())
return;
this._updateChildStatus(assessment, 'group_completion');
var quesChild = new GlideRecord('asmt_assessment_instance_question');
quesChild.addNotNullQuery('instance.sn_grc_parent');
quesChild.addQuery('instance.state', 'NOT IN', 'complete,canceled');
quesChild.addQuery('instance.sn_grc_parent', assessment.getUniqueValue());
quesChild.query();
while (quesChild.next()) {
var isMultipleCheckbox = quesChild.metric.datatype == 'multiplecheckbox' ? true : false;
if (isMultipleCheckbox)
this._deleteChildInstanceQuestion(quesChild);
var quesParent = this._getParentQuestionInstance(assessment, quesChild);
while (quesParent.next()) {
var newQuesChild;
if (isMultipleCheckbox) // create child question record for every parent question record
newQuesChild = this._createChildInstanceQuestion(quesChild);
else
newQuesChild = quesChild;
this._copyResponse(quesParent, newQuesChild);
}
}
this._completeChildAssessment(assessment);
this._updateChildStatus(assessment, 'no_action');
},
_createChildInstanceQuestion: function(quesChild) {
if (!quesChild)
return;
var newQuesChild = new GlideRecord('asmt_assessment_instance_question');
newQuesChild.instance = quesChild.instance;
newQuesChild.category = quesChild.category;
newQuesChild.source_id = quesChild.source_id;
newQuesChild.source_table = quesChild.source_table;
newQuesChild.is_hidden = quesChild.is_hidden;
newQuesChild.metric_type_group = quesChild.metric_type_group;
newQuesChild.metric = quesChild.metric;
newQuesChild.insert();
return newQuesChild;
},
_deleteChildInstanceQuestion: function(quesChild) {
if (!quesChild)
return;
var child = new GlideRecord('asmt_assessment_instance_question');
child.addQuery('instance', quesChild.instance);
child.addQuery('source_id', quesChild.source_id);
child.addQuery('source_table', quesChild.source_table);
child.addQuery('category', quesChild.category);
child.addQuery('metric', quesChild.metric);
child.deleteMultiple();
},
_getParentQuestionInstance: function(parent, quesChild) {
if (!parent || !quesChild)
return;
var quesParent = new GlideRecord('asmt_assessment_instance_question');
quesParent.addNullQuery('instance.sn_grc_parent');
quesParent.addQuery('instance', quesChild.instance.sn_grc_parent);
quesParent.addQuery('category', quesChild.category);
quesParent.addQuery('metric', quesChild.metric);
if (parent.sn_grc_group_type == 'grouped') {
quesParent.addQuery('source_table', quesChild.source_table);
quesParent.addQuery('source_id', quesChild.source_id);
}
if (quesChild.metric.datatype != 'multiplecheckbox') {
quesParent.addQuery('metric.datatype', '!=', 'multiplecheckbox');
quesParent.addQuery('metric_definition', quesChild.metric_definition);
quesParent.setLimit(1);
} else {
quesParent.addQuery('metric.datatype', 'multiplecheckbox');
}
quesParent.query();
return quesParent;
},
_getChildQuestionInstance: function(quesParent) {
if (!quesParent)
return;
var quesChild = new GlideRecord('asmt_assessment_instance_question');
quesChild.addNotNullQuery('instance.sn_grc_parent');
quesChild.addQuery('instance.sn_grc_parent', quesParent.instance);
quesChild.addQuery('source_table', quesParent.source_table);
quesChild.addQuery('source_id', quesParent.source_id);
quesChild.addQuery('metric', quesParent.metric);
quesChild.setLimit(1);
quesChild.query();
if (quesChild.next())
return quesChild;
return;
},
_copyResponse: function(copyFrom, copyTo) {
if (!copyFrom || !copyTo)
return;
copyTo.setValue('add_info', copyFrom.getValue('add_info'));
copyTo.setValue('string_value', copyFrom.getValue('string_value'));
copyTo.setValue('value', copyFrom.getValue('value'));
copyTo.setValue('reference_id', copyFrom.getValue('reference_id'));
copyTo.setValue('metric_definition', copyFrom.getValue('metric_definition'));
copyTo.setValue('is_hidden', copyFrom.getValue('is_hidden'));
if (copyFrom.metric.datatype == 'attachment') {
var glideSysAttachment = new GlideSysAttachment();
this._deleteAllAttachments(copyTo, glideSysAttachment);
var metricResult = this._getMetricResult(copyFrom);
if (metricResult && metricResult.next()) // If group is 'complete' then attachemnts are moved to 'asmt_metric_result', else they are in 'asmt_assessment_instance_question'
glideSysAttachment.copy('asmt_metric_result', metricResult.getUniqueValue(), 'asmt_assessment_instance_question', copyTo.getUniqueValue());
else
glideSysAttachment.copy('asmt_assessment_instance_question', copyFrom.getUniqueValue(), 'asmt_assessment_instance_question', copyTo.getUniqueValue());
}
copyTo.update();
},
_getMetricResult: function(insQues) {
var metricResult = new GlideRecord('asmt_metric_result');
metricResult.addQuery('metric.datatype', 'attachment');
metricResult.addQuery('instance', insQues.getValue('instance'));
metricResult.addQuery('source_id', insQues.getValue('source_id'));
metricResult.addQuery('source_table', insQues.getValue('source_table'));
metricResult.addQuery('metric', insQues.getValue('metric'));
metricResult.setLimit(1);
metricResult.query();
return metricResult;
},
_deleteAllAttachments: function(quesChild, glideSysAttachment) {
if (!quesChild)
return;
if (!glideSysAttachment)
glideSysAttachment = new GlideSysAttachment();
var attachment = new GlideRecord('sys_attachment');
attachment.addQuery('table_name', quesChild.getTableName());
attachment.addQuery('table_sys_id', quesChild.getUniqueValue());
attachment.query();
while (attachment.next())
glideSysAttachment.deleteAttachment(attachment.getUniqueValue());
},
_completeChildAssessment: function(parent) {
if (!parent)
return;
var child = new GlideRecord('asmt_assessment_instance');
child.addQuery('sn_grc_parent', parent.getUniqueValue());
child.addQuery('state', 'NOT IN', 'complete,canceled');
if (parent.sn_grc_group_type == 'consolidated') {
child.setValue('state', 'complete');
child.setValue('percent_answered', parent.percent_answered);
child.updateMultiple();
} else {
child.query();
while (child.next()) {
child.setValue('state', 'complete');
child.setValue('percent_answered', this._getPercentAnswered(child));
child.update();
}
}
},
_getPercentAnswered: function(instance) {
var count = this._calculateQuestionsAnswered(instance);
return (count.ansCount * 100) / count.quesCount;
},
_calculateQuestionsAnswered: function(instance) {
if (!instance)
return;
var count = {
quesCount: 0,
ansCount: 0
};
var map = {};
var insQues = new GlideRecord('asmt_assessment_instance_question');
insQues.addQuery('instance', instance.getUniqueValue());
insQues.query();
while (insQues.next()) {
if (map[insQues.metric])
continue;
map[insQues.metric] = true;
if (insQues.metric && insQues.metric.depends_on) {
if (this._satisfiesParentQuestion(insQues, insQues.metric.depends_on))
count = this._increaseCount(insQues, count);
} else
count = this._increaseCount(insQues, count);
}
return count;
},
_increaseCount: function(insQues, count) {
if (!insQues || !count)
return count;
count.quesCount++;
if (this._isAnswered(insQues))
count.ansCount++;
return count;
},
_satisfiesParentQuestion: function(child, parent_id) {
if (!child || !child.metric || !parent_id)
return false;
var parent = new GlideRecord('asmt_assessment_instance_question');
parent.addQuery('instance', child.instance);
parent.addQuery('metric', parent_id);
parent.setLimit(1);
parent.query();
if (!parent.next())
return false;
if (parent.metric.datatype == 'template')
return this._contains(child.metric.displayed_when_template, 'template', parent.metric.template, parent.value);
else if (parent.metric.datatype == 'checkbox')
return child.metric.displayed_when_checkbox == parent.value;
else if (parent.metric.datatype == 'boolean')
return child.metric.displayed_when_yesno == parent.value;
return this._contains(child.metric.displayed_when, 'metric', parent.metric, parent.value);
},
_contains: function(sys_ids, type, ques_id, value) {
if (!sys_ids || !type || !ques_id || !value)
return false;
if (type != 'metric' && type != 'template')
return false;
var choice = new GlideAggregate('asmt_' + type + '_definition');
choice.addQuery('sys_id', 'IN', sys_ids);
choice.addQuery(type, ques_id);
choice.addQuery('value', value);
choice.addAggregate('COUNT');
choice.query();
if (choice.next())
return choice.getAggregate('COUNT') > 0;
else
return false;
},
_isAnswered: function(insQues) {
if (!insQues || !insQues.metric)
return false;
if (insQues.metric.datatype == 'attachment')
return this._hasAttachment(insQues);
else if (insQues.metric.datatype == 'string')
return !insQues.string_value.nil();
else if (insQues.metric.datatype == 'reference')
return !insQues.reference_id.nil();
else if (!insQues.value.nil())
return true;
return false;
},
_hasAttachment: function(quesInstance) {
if (!quesInstance)
return;
var attach = new GlideAggregate('sys_attachment');
attach.addQuery('table_name', 'asmt_assessment_instance_question');
attach.addQuery('table_sys_id', quesInstance.getUniqueValue());
attach.addAggregate('COUNT');
attach.query();
if (attach.next())
return attach.getAggregate('COUNT') > 0;
else
return false;
},
_updateChildStatus: function(parent, status) {
if (!parent)
return;
if (!status || status == '')
status = 'NULL';
var child = new GlideRecord('asmt_assessment_instance');
child.addQuery('sn_grc_parent', parent.getUniqueValue());
child.setValue('sn_grc_status', status);
child.setValue('taken_on', new GlideDateTime());
child.updateMultiple();
},
type: 'GRCAssessmentUtilsBase'
};
Sys ID
a40a3956d7231200bbc783e80e610384