Assignment rules allow you to specify conditions for which a particular assignment group and/or assigned to person should be assigned to work on a particular task. Assignment rules work fine, but as I’ve worked with clients I’ve come across some common scenarios that can’t be solved with the out-of-box setup. The primary issue with assignment rules is that they only run as a record is submitted and they only run if an assignment has not been made already to the ticket being saved. Along with this, most organizations I’ve worked with choose to make the ‘Assignment group’ field mandatory. Because of this, the person working the ticket always has to make some sort of assignment before saving the record (meaning that the assignment rules never get run). I learned how to work around this issue on one of my very first Service-now implementations and I almost always implement this solution as part of any Incident Management rollout. The out-of-box assignment rules are documented here. This article shows how you can apply the same customizations to your Service-now implementation that I use for my clients. This entire customization has also been packaged into an ‘Assignment Rule Lookup’ update set to save time in implementing.

This customization includes the following features:

  • Easy to view and manage lookup table for common assignments
  • Dynamic lookup/population of assignment values as you work on the Incident form

This article is provided for documentation purposes. Although you can easily follow the steps outlined here, it may be easier just to use the ‘Assignment Rule Lookup’ update set. The update set is designed to allow you to populate assignment rule lookup records for Incident assignments. The criteria for looking up these assignments is based off of the ‘Category’, ‘Subcategory’, and ‘Configuration item’ fields (although it is very simple to extend this if desired). Through the use of client scripts, assignments can also be populated as form values change.

The first step in applying this customization is to create an assignment lookup table that can store all of the different combinations of values used to determine assignments. The update set includes this table for you (which can be managed from the ‘System Policy -> Assignment lookup’ module). Security setup for this table is also included, but is not documented in this article.

Assignment Lookup Table
—Table and field settings (along with necessary dictionary changes)—
Table: Assignment Lookup
Fields:
Category – Choice field (Uses the Incident table and Category field as choice table and field)
Subcategory – Choice field (Uses the Incident table and Subcategory field as choice table and field. Also needs to be made dependent on the ‘u_category’ field)
Configuration item (‘u_cmdb_ci’) – Reference field referencing the ‘Configuration Item’ table
Assignment group – Reference field referencing the ‘Group (sys_user_group)’ table
Assigned to – Reference field referencing the ‘User (sys_user)’ table

Once the ‘Assignment lookup’ table is created and populated, we need to create an assignment rule that can query that table and return assignments based on the information found. You can create a new assignment rule by navigating to ‘System Policy -> Assignment’. I usually set my assignment rule up with a very low order value and a condition that ensures it will always get evaluated. The assignment rule provided in the update set has the following settings…

Assignment lookup rule
Name: Assignment lookup rule
Table: Incident
Match conditions: All
Execution order: 10
Group/User: empty
Condition: Assignment Group is empty
Script:

var lookup = new GlideRecord('u_assignment_lookup');
var query = false;

//Category check
if(current.category){
   query = true;
   lookup.addQuery('u_category', current.category);

   //Subcategory check
   if(current.subcategory){
      lookup.addQuery('u_subcategory', current.subcategory);
   }
   else{
      lookup.addQuery('u_subcategory', '');
   }

   //CI check
   if(current.cmdb_ci){
      lookup.addQuery('u_cmdb_ci', current.cmdb_ci);
   }
   else{
      lookup.addQuery('u_cmdb_ci', '');
   }
}

//If no category check for a CI
if(!current.category && current.cmdb_ci){
   query = true;
   lookup.addQuery('u_cmdb_ci', current.cmdb_ci);
   lookup.addQuery('u_category', '');
   lookup.addQuery('u_subcategory', '');
}

//Run the query if we have a value to look for
if(query == true){
   lookup.query();

   if (lookup.next()){
      /*gs.log('category: ' + current.category + '  subcategory: ' + current.subcategory + '  cmdb_ci: ' + current.cmdb_ci + ' assignmentGroup: ' + lookup.u_assignment_group.name + '  assigned_to: ' + lookup.u_assigned_to.name);*/
      current.assignment_group = lookup.u_assignment_group;
      current.assigned_to = lookup.u_assigned_to;
   }
   else{
      current.assignment_group = '';
      current.assigned_to = '';
   }
}
//Return empty if no values to look for
else{
  current.assignment_group = '';
  current.assigned_to = '';
}

The final step is to configure the ability to have assignments populate as fields on the form get changed. In order to accomplish this, we create an ‘onChange’ client script with the following settings…

‘AJAX Assignment’ Client Script

This client script needs to be applied to every field that should cause an assignment lookup. In my setup, the client script has been set up for the Category, Subcategory, and Configuration item fields on the Incident table.

Name: AJAX Assignment (Category)
Table: Incident
Type: onChange
Field name: Category
Script:

//
//Make an AJAX request to the server to get who this incident would be assigned to
//given the current values in the record. This will run the assignment rules that
//have been defined in System Policy and return the assigned_to and the assignment_group
//
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading)
return; // Form load, do not do anything

//
//Construct the URL to ask the server for the assignment
//
var url = 'xmlhttp.do?sysparm_processor=AJAXAssignment&sys_target=incident';
var uv = gel('sys_uniqueValue');
if (uv)
url += '&sys_uniqueValue=' + uv.value;
//Make the AJAX request to the server and get the response
var serial = g_form.serialize(); // get all values currently assigned to the incident
var response = ajaxRequest(url, serial, false);
var item = response.responseXML.getElementsByTagName('item')[0];
//Process the item returned by the server
if (item) {
//Get the assigned_to ID and its display value and put them on the form
var name = item.getAttribute('name');
var name_label = item.getAttribute('name_label');
if (name_label != null && name != null)
g_form.setValue('assigned_to', name, name_label);
else
g_form.setValue('assigned_to', null);
//Get the assignment_group ID and its display value and put then on the form
var group = item.getAttribute('group');
var group_label = item.getAttribute('group_label');
if (group_label != null && group != null)
g_form.setValue('assignment_group', group, group_label);
else
g_form.setValue('assignment_group', null);
}
}

Related Links: