- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-29-2017 01:50 PM
Hi,
I am trying to create a assessment instance by running the schedule job script. Job was running but record is not getting inserted in the assessment table. Below is the script I am using:
sys_id in the script is assessment metric type sys_id
var inc1 = new GlideRecord("incident");
inc1.addEncodedQuery("resolved_at>=javascript:gs.daysAgoStart(14)");
inc1.addQuery("priority",1);
inc1.query();
while (inc1.next()) {
gs.log("before");
new sn_assessment_core.AssessmentCreation().createAssessments(inc1, 'd6818afa4f914700990f843e0210c7fb');
gs.log("after");
}
Thanks in advance
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-29-2017 02:05 PM
Hmm, your code doesn't seem to comply with the extant documentation regarding how to generate an assessment.
Instead, try something more like this:
var inc1 = new GlideRecord("incident");
inc1.addEncodedQuery("resolved_at>=javascript:gs.daysAgoStart(900)");
inc1.addQuery("priority", 1);
inc1.query();
while (inc1.next()) {var asmtResult = new SNC.AssessmentCreation().CreateAssessments(asmtTypeSysId, incl.getValue('sys_id'), sysIdOfUser);
}
That's the "documented" solution, but I haven't tested it so I don't want to leave you hanging in case that doesn't work. So, here's a solution I have tested, which uses the OOB AssessmentUtils Script Include:
var asmtUtils = new AssessmentUtils();
/**
* @param typeId {string} The sys_id of the metric type or survey definition for which to generate assessments or surveys.
* @param sourceId {string} One or more comma-separated sys_ids of records to include in the assessments generated.
* There must be an assessable record associated with the specified metric type for each source record. If this parameter
* is left blank, the assessments generated include all assessable records for the specified type. This parameter is for
* use with assessments only.
* @param userId {string} One or more comma-separated sys_ids of users to which to send assessment or survey instances.
* If this parameter is left blank, the assessment stakeholders or survey users receive instances. This parameter is
* required for on-demand assessments.
* @param groupId
* @description Hard-coding sys_id because this is a demo, so all sins are absolved after the purge.
*/
var asmtResult = asmtUtils.createAssessments(metricTypeSysID, ideaSysID, userSysID);
asmtResult = asmtResult.split(',');
Note my JSDoc-formatted comments above the usage of the createAssessments method of the AssessmentUtils class. This should tell you everything you need to know about how to use this method.
For a fuller bit of context, here's a whole script include I once wrote that deals with assesments. It has some specific functionality built for a very specific purpose, but you can get an idea of how all the moving parts seem to work. :
var ClientIdeaAssessmentUtils = Class.create();
ClientIdeaAssessmentUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {checkAndGenerateAssessment: function() {
var returnObj = {
assessmentListUrl: gs.getProperty('glide.servlet.uri') + 'ASSESSMENT_TABLE_NAME_HERE' + '_list.do?sysparm_show=user',
error: false,
errorMsg: ''
};
//Hard-coding this value for the demo.
var metricTypeSysID = 'SYS_ID_HERE'; //todo: cleanse thyself of this hard-coded abombinationvar ideaSysID = this.getParameter('sysparm_idea_sys_id');
var userSysID = this.getParameter('sysparm_user_sys_id');
var distroList = this.getParameter('sysparm_distro_list');var asmtAlreadyExists = this._doesAssessmentExist(metricTypeSysID, ideaSysID, userSysID);
var distroListChanged = this._didDistroListChange(ideaSysID, distroList);
/*We can't check if the user
is in the new distro list as well, because the distro lists are maintained outside of ServiceNow.
Therefore, we must deactivate their link once the distro list changes. */if (asmtAlreadyExists) {
returnObj.error = true;
returnObj.errorMsg = 'It looks like you\'ve already filled out an assessment for this Idea.';
} else if (distroListChanged) {returnObj.error = true;
returnObj.errorMsg = 'It looks like the distribution list for this Idea has been changed, so this assessment has been invalidated.';
} else {var asmtUtils = new AssessmentUtils();
/**
* @param typeId {string} The sys_id of the metric type or survey definition for which to generate assessments or surveys.
* @param sourceId {string} One or more comma-separated sys_ids of records to include in the assessments generated.
* There must be an assessable record associated with the specified metric type for each source record. If this parameter
* is left blank, the assessments generated include all assessable records for the specified type. This parameter is for
* use with assessments only.
* @param userId {string} One or more comma-separated sys_ids of users to which to send assessment or survey instances.
* If this parameter is left blank, the assessment stakeholders or survey users receive instances. This parameter is
* required for on-demand assessments.
* @param groupId
* @description Hard-coding sys_id because this is a demo, so all sins are absolved after the purge.
*/
var asmtResult = asmtUtils.createAssessments(metricTypeSysID, ideaSysID, userSysID);
asmtResult = asmtResult.split(',');//Removed since we're just redirecting the user to their assessments page no matter what.
// Also, I think there was some kind of issue with this.
/*
returnObj.redirectUrl = gs.getProperty('glide.servlet.uri') +
'/assessment_take2.do?sysparm_assessable_sysid=' +
//Sys_id of assessment instance from asmt_assessment_instance table
asmtResult[0].trim() +
'&sysparm_assessable_type=' +
//sys_id of the assessment metric type from asmt_metric_type table
metricTypeSysID;
*/
}return JSON.stringify(returnObj);
},_didDistroListChange: function(ideaSid, requestDistroList) {
var ideaDistroList;
var grIdea = new GlideRecord('idea');
if (grIdea.get(ideaSid)) {this.grIdea = grIdea; //I wanted this in Class-scope for future enhancements
ideaDistroList = grIdea.u_distribution_list.getDisplayValue();
ideaDistroList = ideaDistroList.toLowerCase();
return (ideaDistroList.toLowerCase() != requestDistroList.toLowerCase());
} else {gs.error('Unable to locate idea with sys_id: ' + ideaSid);
gs.addErrorMessage('Unable to locate idea with sys_id: ' + ideaSid);
return false;
}},
_doesAssessmentExist: function(metricTypeSid, ideaSid, userSid) {
var encodedQuery = 'source_id=' + ideaSid +
//Removing the below line because we don't actually care if it's active or not, we just want to know if one exists for this Idea.
//'^instance.metric_type.active=true' +
'^instance.metric_type.evaluation_method=assessment' +'^instance.user=' + userSid +
'^instance.stateINready,wip^source_table=tsp5_idea' +
'^instance.metric_type=' + metricTypeSid;
var gr = new GlideRecord('asmt_assessment_instance_question');
gr.addEncodedQuery(encodedQuery);
gr.setLimit(1);
gr.query();
return gr.hasNext();
},/*_getAssessmentUrl: function() {
var grCatItems = new GlideRecord('asmt_assessment_instance_question');
//todo},*/
type: 'ClientIdeaAssessmentUtils'
});
I also recommend against hard-coding the assessment type sys_id. Best to run a query on the assessment type table to grab it or, worst-case scenario, at least document your code so it shows which record you EXPECT to be getting with that sys_id, and from what table.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-29-2017 02:05 PM
Hmm, your code doesn't seem to comply with the extant documentation regarding how to generate an assessment.
Instead, try something more like this:
var inc1 = new GlideRecord("incident");
inc1.addEncodedQuery("resolved_at>=javascript:gs.daysAgoStart(900)");
inc1.addQuery("priority", 1);
inc1.query();
while (inc1.next()) {var asmtResult = new SNC.AssessmentCreation().CreateAssessments(asmtTypeSysId, incl.getValue('sys_id'), sysIdOfUser);
}
That's the "documented" solution, but I haven't tested it so I don't want to leave you hanging in case that doesn't work. So, here's a solution I have tested, which uses the OOB AssessmentUtils Script Include:
var asmtUtils = new AssessmentUtils();
/**
* @param typeId {string} The sys_id of the metric type or survey definition for which to generate assessments or surveys.
* @param sourceId {string} One or more comma-separated sys_ids of records to include in the assessments generated.
* There must be an assessable record associated with the specified metric type for each source record. If this parameter
* is left blank, the assessments generated include all assessable records for the specified type. This parameter is for
* use with assessments only.
* @param userId {string} One or more comma-separated sys_ids of users to which to send assessment or survey instances.
* If this parameter is left blank, the assessment stakeholders or survey users receive instances. This parameter is
* required for on-demand assessments.
* @param groupId
* @description Hard-coding sys_id because this is a demo, so all sins are absolved after the purge.
*/
var asmtResult = asmtUtils.createAssessments(metricTypeSysID, ideaSysID, userSysID);
asmtResult = asmtResult.split(',');
Note my JSDoc-formatted comments above the usage of the createAssessments method of the AssessmentUtils class. This should tell you everything you need to know about how to use this method.
For a fuller bit of context, here's a whole script include I once wrote that deals with assesments. It has some specific functionality built for a very specific purpose, but you can get an idea of how all the moving parts seem to work. :
var ClientIdeaAssessmentUtils = Class.create();
ClientIdeaAssessmentUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {checkAndGenerateAssessment: function() {
var returnObj = {
assessmentListUrl: gs.getProperty('glide.servlet.uri') + 'ASSESSMENT_TABLE_NAME_HERE' + '_list.do?sysparm_show=user',
error: false,
errorMsg: ''
};
//Hard-coding this value for the demo.
var metricTypeSysID = 'SYS_ID_HERE'; //todo: cleanse thyself of this hard-coded abombinationvar ideaSysID = this.getParameter('sysparm_idea_sys_id');
var userSysID = this.getParameter('sysparm_user_sys_id');
var distroList = this.getParameter('sysparm_distro_list');var asmtAlreadyExists = this._doesAssessmentExist(metricTypeSysID, ideaSysID, userSysID);
var distroListChanged = this._didDistroListChange(ideaSysID, distroList);
/*We can't check if the user
is in the new distro list as well, because the distro lists are maintained outside of ServiceNow.
Therefore, we must deactivate their link once the distro list changes. */if (asmtAlreadyExists) {
returnObj.error = true;
returnObj.errorMsg = 'It looks like you\'ve already filled out an assessment for this Idea.';
} else if (distroListChanged) {returnObj.error = true;
returnObj.errorMsg = 'It looks like the distribution list for this Idea has been changed, so this assessment has been invalidated.';
} else {var asmtUtils = new AssessmentUtils();
/**
* @param typeId {string} The sys_id of the metric type or survey definition for which to generate assessments or surveys.
* @param sourceId {string} One or more comma-separated sys_ids of records to include in the assessments generated.
* There must be an assessable record associated with the specified metric type for each source record. If this parameter
* is left blank, the assessments generated include all assessable records for the specified type. This parameter is for
* use with assessments only.
* @param userId {string} One or more comma-separated sys_ids of users to which to send assessment or survey instances.
* If this parameter is left blank, the assessment stakeholders or survey users receive instances. This parameter is
* required for on-demand assessments.
* @param groupId
* @description Hard-coding sys_id because this is a demo, so all sins are absolved after the purge.
*/
var asmtResult = asmtUtils.createAssessments(metricTypeSysID, ideaSysID, userSysID);
asmtResult = asmtResult.split(',');//Removed since we're just redirecting the user to their assessments page no matter what.
// Also, I think there was some kind of issue with this.
/*
returnObj.redirectUrl = gs.getProperty('glide.servlet.uri') +
'/assessment_take2.do?sysparm_assessable_sysid=' +
//Sys_id of assessment instance from asmt_assessment_instance table
asmtResult[0].trim() +
'&sysparm_assessable_type=' +
//sys_id of the assessment metric type from asmt_metric_type table
metricTypeSysID;
*/
}return JSON.stringify(returnObj);
},_didDistroListChange: function(ideaSid, requestDistroList) {
var ideaDistroList;
var grIdea = new GlideRecord('idea');
if (grIdea.get(ideaSid)) {this.grIdea = grIdea; //I wanted this in Class-scope for future enhancements
ideaDistroList = grIdea.u_distribution_list.getDisplayValue();
ideaDistroList = ideaDistroList.toLowerCase();
return (ideaDistroList.toLowerCase() != requestDistroList.toLowerCase());
} else {gs.error('Unable to locate idea with sys_id: ' + ideaSid);
gs.addErrorMessage('Unable to locate idea with sys_id: ' + ideaSid);
return false;
}},
_doesAssessmentExist: function(metricTypeSid, ideaSid, userSid) {
var encodedQuery = 'source_id=' + ideaSid +
//Removing the below line because we don't actually care if it's active or not, we just want to know if one exists for this Idea.
//'^instance.metric_type.active=true' +
'^instance.metric_type.evaluation_method=assessment' +'^instance.user=' + userSid +
'^instance.stateINready,wip^source_table=tsp5_idea' +
'^instance.metric_type=' + metricTypeSid;
var gr = new GlideRecord('asmt_assessment_instance_question');
gr.addEncodedQuery(encodedQuery);
gr.setLimit(1);
gr.query();
return gr.hasNext();
},/*_getAssessmentUrl: function() {
var grCatItems = new GlideRecord('asmt_assessment_instance_question');
//todo},*/
type: 'ClientIdeaAssessmentUtils'
});
I also recommend against hard-coding the assessment type sys_id. Best to run a query on the assessment type table to grab it or, worst-case scenario, at least document your code so it shows which record you EXPECT to be getting with that sys_id, and from what table.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-02-2017 08:42 AM
Hi Timothy,
Thanks for your response. I want to send a survey to specific group. For this, I have created Survey User groups and assigned the group to the particular survey.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-07-2020 08:21 AM
Hi Pavan,
After all these years you probably have no interest in Assessments any more. And what I have just found may be completely unrelated to your issue. But I was also finding no assessment instances being generated when the scheduled job associated with the metric type ran.
I've only recently started working on Assessments so it's all new to me. The reason it wasn't working for me was that you have to have Assessable Records associated with the individual metric categories. Each Metric Category has a filter condition to say which of the parent Metric Type's Assessable Records should be associated with the Category. Trouble being that if you leave that filter condition empty, it means NO records. Whereas everywhere else, leaving a filter condition empty means ALL records.
Their recommendation is to either use the same filter condition on the Categories as used on the Metric Type. Or use a filter condition of "Sys ID is not empty".
That's in this Docs page: https://docs.servicenow.com/bundle/orlando-servicenow-platform/page/administer/assessments/task/t_Ma...
Which worked for me! Really odd and unintuitive that it should work that way. And not great that in the UI it doesn't warn you, or even default the condition to being "Sys ID is not empty". Or even work the way you'd expect it to work, and have no filter condition meaning ALL records rather than NO records.
Regards
Michael