Assign survey from workflow using catalog item variable and associating with RITM

Tamara11
Mega Sage

We have a catalog item for which we need to assign a survey to a user listed in a reference variable upon submission. 

I've been able to assign the survey from the workflow, but the method I'm using doesn't associate it with the ritm as it would if I were using a trigger condition. The trigger condition though, doesn't appear to allow me to access the variable in the Catalog Item.

This code in my workflow will create the survey and assign it using the variable, but it doesn't associate it with the Requested Item.

(new SNC.AssessmentCreation()).createAssessments('5c2112d31b60095048b354a51a4bcb32', '', current.variables.access_requested_for);

I tried to manually edit the Trigger ID field on the assessment instance and it looks the same as the ones that were generated through the trigger condition, but it still doesn't show up in the Assessment Instances tab when viewing the RITM.

Can someone help me get this working?

1 ACCEPTED SOLUTION

Tamara11
Mega Sage

So, in case anyone else needs to do this, here's how I made this happen.  I did not kick the survey off from the workflow. Instead, I paused the workflow until the survey was completed.

  • I created the survey and set a trigger condition on the sc_req_item table with the condition: Item is <My Catalog Item>.

    Because the trigger condition requires a user field, but does not let us access variables from our Catalog Items, I used Requested For for the User field.

 

  • ServiceNow auto-creates the business rule associated with Survey Trigger Conditions. In this case, it was named Auto assessment business rule.  There is a read-only Business Rule field on the Trigger Condition form that will contain the name of your Business Rule.

  • I edited my Business Rule Script to make it temporarily put the "Requested For" value into a placeholder and assigned my variable value to Requested For.  This allowed the Survey Assignment call to work as intended and then after the Survey call, I put the original value back into "Requested For."
function onAfter(current, previous){ 
        // store existing value of Requested For field, to be put back later
	var holduser = current.requested_for.toString();

        // assign value of Catalog Item variable "access requested for" to Requested For
	current.requested_for = current.variables.access_requested_for;
         
         // assign the survey
	(new sn_assessment_core.AssessmentCreation()).conditionTrigger(current, '21a98d4c1b38895048b354a51a4bcb3b'); 
	
        // put Requested For value back the way we found it.
	current.requested_for = holduser;
 }
  • Then, in my workflow, I added a Wait for Condition with the script below:
// Set the variable 'answer' to true or false to indicate if the condition has been met or not.

     // Create an assessment instance to hold values:
     var grAsmt = new GlideRecord('asmt_assessment_instance');
    // Assign sys_id of current RITM to variable
     var ritmNum = current.sys_id;

     // Query asmt_assessment_instance for our survey
     grAsmt.addQuery('trigger_id', 'CONTAINS', current.sys_id);
     grAsmt.query();

     // Check for completed state     
     while(grAsmt.next()) { 
	
	if(grAsmt.state == 'complete'){
		answer = true;
	}
     }

 

  • Because the Wait for Condition won't do anything until the RITM we're working on is updated, I decided to make another Business Rule. It runs on the asmt_assessment_instance table and when the survey is completed, adds a Work Note to the RITM indicating the completion and noting the Assessment Number.  

find_real_file.png

find_real_file.png

The script:

(function executeRule(current, previous /*null when async*/) {

  var req = new GlideRecord('sc_req_item');
 
  req.addQuery('sys_id', current.trigger_id);
  req.query();

  while (req.next()) {
 
   req['work_notes'].setJournalEntry("Attestation completed: " + current.number);
   req.update();
  }
})(current, previous);

Now the workflow can move on and do the rest of the stuff.

 

This seems really convoluted to me, and I am open to a more elegant solution if anyone knows of it. 

View solution in original post

1 REPLY 1

Tamara11
Mega Sage

So, in case anyone else needs to do this, here's how I made this happen.  I did not kick the survey off from the workflow. Instead, I paused the workflow until the survey was completed.

  • I created the survey and set a trigger condition on the sc_req_item table with the condition: Item is <My Catalog Item>.

    Because the trigger condition requires a user field, but does not let us access variables from our Catalog Items, I used Requested For for the User field.

 

  • ServiceNow auto-creates the business rule associated with Survey Trigger Conditions. In this case, it was named Auto assessment business rule.  There is a read-only Business Rule field on the Trigger Condition form that will contain the name of your Business Rule.

  • I edited my Business Rule Script to make it temporarily put the "Requested For" value into a placeholder and assigned my variable value to Requested For.  This allowed the Survey Assignment call to work as intended and then after the Survey call, I put the original value back into "Requested For."
function onAfter(current, previous){ 
        // store existing value of Requested For field, to be put back later
	var holduser = current.requested_for.toString();

        // assign value of Catalog Item variable "access requested for" to Requested For
	current.requested_for = current.variables.access_requested_for;
         
         // assign the survey
	(new sn_assessment_core.AssessmentCreation()).conditionTrigger(current, '21a98d4c1b38895048b354a51a4bcb3b'); 
	
        // put Requested For value back the way we found it.
	current.requested_for = holduser;
 }
  • Then, in my workflow, I added a Wait for Condition with the script below:
// Set the variable 'answer' to true or false to indicate if the condition has been met or not.

     // Create an assessment instance to hold values:
     var grAsmt = new GlideRecord('asmt_assessment_instance');
    // Assign sys_id of current RITM to variable
     var ritmNum = current.sys_id;

     // Query asmt_assessment_instance for our survey
     grAsmt.addQuery('trigger_id', 'CONTAINS', current.sys_id);
     grAsmt.query();

     // Check for completed state     
     while(grAsmt.next()) { 
	
	if(grAsmt.state == 'complete'){
		answer = true;
	}
     }

 

  • Because the Wait for Condition won't do anything until the RITM we're working on is updated, I decided to make another Business Rule. It runs on the asmt_assessment_instance table and when the survey is completed, adds a Work Note to the RITM indicating the completion and noting the Assessment Number.  

find_real_file.png

find_real_file.png

The script:

(function executeRule(current, previous /*null when async*/) {

  var req = new GlideRecord('sc_req_item');
 
  req.addQuery('sys_id', current.trigger_id);
  req.query();

  while (req.next()) {
 
   req['work_notes'].setJournalEntry("Attestation completed: " + current.number);
   req.update();
  }
})(current, previous);

Now the workflow can move on and do the rest of the stuff.

 

This seems really convoluted to me, and I am open to a more elegant solution if anyone knows of it.