Assignment Rule Lookup

//Assignment Rule Lookup

Assignment Rule Lookup

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:

By | 2018-07-09T15:00:11-06:00 April 19th, 2010|Categories: System Definition|Tags: , , |28 Comments

About the Author:

28 Comments

  1. Matthew July 13, 2010 at 10:38 am - Reply

    Mark,

    This is a great functionality and would help a lot. However, I have a few questions which I am hoping you can help me with. I am dealing with a customer who has more than a few hundred assignment rules, so I built them a template where they can import their assignment rules rather than creating one by one. The conditions get to be imported fine, but they do not reference back to the actual values of the Category/subcategory. My questions are:

    1- Is there a way to do this through script to make a look of to those condition reference fields?!

    2- Does SN/you have any better suggestion in such a cases(many assignment rule) and how to deal with them easily?!

    I would really appreciate any comments/feedback you may have.

    Here is an example of the template:

    Name Table Match conditions Group User Execution Order Conditions

    Rule 01 incident All CAI 100 u_category=Communications^u_subcategory=Voice Mail^u_activity_issue=Power Failure^EQ

    • Mark Stanger July 14, 2010 at 12:30 am - Reply

      I hope I’m understanding everything from your comment, but my recommendation is to use the solution above. The way that it works makes it so that you really only have 1 assignment rule per table. You just make the condition on the assignment rule generic enough so that it always gets run for a particular table. One of the benefits of this solution is that you don’t have to worry about all of the different conditions…you just set those conditions up in your lookup table and the assignment rule just queries that table to get its answer…

      So, for the example you provided, I would have an assignment lookup record with a category, subcategory, and activity issue defined (along with the assignment group and person to return). When my assignment rule script hits that record you’ll return the correct assignments from it…all with just a single assignment rule for the entire incident table.

  2. Matthew July 14, 2010 at 10:59 am - Reply

    Mark,

    Thank you for your response. Unfortunately, I didn’t see your comment until now and sorry for being late. Your solution is wonderful, however I have made several customization to the client instance which will make it difficult to use this. This customer has more that 1500 choices of category/subcat/activity/issue, and needed to filter the CI base on the combination choice of these CTIs. Therefore,we had to design a separate incident classification table where it would filter the list of available CIs base on the cat/subcat choices. Thsi means on the incident table we do not point at sys_choices table and instead make a look up into this table”incident classification”. Having that said, how do you think I can use the assignment rules and building them with this complexity. Thank you for your time in advance.

    • Mark Stanger July 14, 2010 at 3:17 pm - Reply

      I honestly don’t have any idea based on what you’ve described. With that kind of complexity, I can almost guarantee that the simplest route would be to do some sort of lookup from a single assignment rule script that would handle everything. Based on my experience, I would never go down the route of having multiple different assignment rules per table again. I’m not sure what the necessary script configuration would be for your client though.

    • Mark Stanger July 16, 2010 at 3:49 pm - Reply

      Matthew,
      I’ve removed your last comment with your script. If you have custom modifications that you’ve made and you need help with some script debugging then you’ll need to ask on the Service-now forums. It’s simply not something I can support to debug custom scripts for people who make changes to this solution.

  3. Jim Uomini July 27, 2010 at 4:10 am - Reply

    This solution allowed me to reduce 21 assignment rules to 1 for one of my tables. It was easy to install and easy to modify for a different table and field names. Thanks Mark.

    • Mark Stanger July 27, 2010 at 4:11 am - Reply

      That’s great to hear Jim! Thanks for commenting.

  4. Mark Stanger August 5, 2010 at 8:03 am - Reply

    I just found (and fixed) an issue with this functionality that only happens in Internet Explorer. If you have previously set up assignment rules using the article above or the associated update set you’ll want to update any ‘AJAX Assignment’ client scripts in your instances with the new code from the ‘AJAX Assignment Client Script’ section above.

  5. Tony Fugere January 11, 2011 at 10:42 am - Reply

    This is an “old” posting, but man I have to hand it to you, Mark. This is easily one of my favorites. Especially when a client asks for this to be extended to custom fields. You’ve designed this perfectly for easy extension. I just added a third Choice (“sub-sub-category”) as well as a True/False checkbox to Incident that are both used in the Assignment process. I was able to simply add the columns to the lookup, copy/paste some code from the Rule and I was on my way! Thanks for kicking butt on this stuff as usual.

    • Mark Stanger January 12, 2011 at 3:05 am - Reply

      Wow. Thanks for the props! I’m glad somebody showed this solution to me right when I got started at Service-now. It’s saved me more than once too. I’m glad to hear it’s not too difficult to work with.

  6. Ajay January 18, 2011 at 3:03 am - Reply

    HI Mark…

    how we need to do the same for service catalog requests.

    We have multiple locations and all the requests should go to their own contry service desk reps. How can i create a rule for service requests based up on country or location.

    Thanks

    Ajay

    • Mark Stanger January 18, 2011 at 3:22 am - Reply

      That would depend completely on your specific setup. Typically, requests and request items aren’t assigned to groups at all. It’s the tasks underneath those items that get assigned. If you are doing direct request assignments for some reason, you would not need a solution like I’ve described here. You would probably just need a standard assignment rule script that would get the ‘requested_for’ person’s location and then query for the group in that location. Groups don’t have locations out-of-box so that script would depend entirely on your system setup. In the end, your assignment rule script would need to set the assignment group like this…

      current.assignment_group = assignmentGroupSys_ID;
       
      ...or...
       
      current.assignment_group.setDisplayValue('Assignment Group Name');
      • Ajay January 18, 2011 at 12:28 pm - Reply

        Thank you Mark.

        We have some cases where we need to assign some request directly to the groups.

        Y es i just went through the catalogog assignment and went through the fulfillment groups.and sure that had helped me a lot am working on creating the fulfillment groups and make those task work with the required groups.

        Thats works….and thank you very much for your reply.

        Thanks

        Ajay

  7. max July 27, 2011 at 8:59 pm - Reply

    Hi Mark,
    i am trying to apply this solution for change request module but it is not working.
    1- I created u_assignment_lookup2
    2- I created fields as per u_assignment_lookup within u_assignment_lookup2 table
    3- I created client scrips for category, subcategory and cmdb_ci and for each script i changed incidents by change_request
    var url = “xmlhttp.do?sysparm_processor=AJAXAssignment&sys_target=change_request”;
    4- I added a record in the u_assignment_lookup2 table
    tested but did not work,
    any clue?
    regards,

    • Mark Stanger July 28, 2011 at 2:26 am - Reply

      Based on this list it looks like you’re missing the actual assignment rule for the change request table.

      • max July 28, 2011 at 5:01 pm - Reply

        i forgot it.
        i created a assignment rule called assignment lookup rule related to the change_request table.
        in this rule i change the first line only to be:
        var lookup = new GlideRecord(‘u_assignment_lookup2’);

        regards,
        max

  8. Ceul August 10, 2011 at 2:55 am - Reply

    Hi Mark,

    I’ve implemented assignment lookup on incident. It work great ! thanks.
    I’m trying to implement the same system on the catalog task table (sc_task).
    I’ve create the Assignment lookup rule script on the sc_task table.

    My problem is that this script is not called by the “AJAX Assignment (…)” client scripts that I’ve create on the sc_task form.
    The only modification I do on these script is to change the name on the table from
    after //Construct the URL to ask the server for the assignment
    var url = “xmlhttp.do?sysparm_processor=AJAXAssignment&sys_target=incident”;
    to
    var url = “xmlhttp.do?sysparm_processor=AJAXAssignment&sys_target=sc_task”;

    Could you give me an advise on what to do more to make assignment lookup work on sc_task table ?
    (I see that the “Assignment lookup rule” is not called because I put a gs.log that didn’t appear in the log after execution of the sevveral steps…)

    Thanks in advance,

    • Mark Stanger August 10, 2011 at 6:36 am - Reply

      That’s the only modification you need to make. The rest should be identical to the incident setup. In general, you need 3 things to make this setup work though…
      1) An ‘onChange’ client script on the table you want to make assignments on. You need to make sure that you’re changing the field that corresponds to the ‘onChange’ client script.
      2) An assignment rule for your new table. This assignment rule should be identical to the one used for incident.
      3) An assignment lookup record that tells the assignment rule which category, subcategory, and CI should trigger the assignment.

      You have to remember with all of these that the incident setup only cares about category, subcategory, and CI. If you are using different fields on sc_task, then it isn’t going to work without some modifications in all 3 places. You can troubleshoot your client script by adding alert messages at various points. You can troubleshoot the assignment rule by adding ‘gs.addInfoMessage’ lines at various points.

      • Ceul August 12, 2011 at 10:12 am - Reply

        Thanks a lot Mark it works fine !

  9. Mirhus August 12, 2011 at 11:37 am - Reply

    I’ve implemented assignment lookup on incident. It work great ! thanks.

  10. max August 14, 2011 at 5:31 pm - Reply

    Hi Mark,
    It works now.
    I missed a little thing.
    Much appreciate it
    Max

  11. Pierre March 15, 2012 at 3:46 am - Reply

    Hi Mark,
    I know it’s an old post, but it’s really great!
    It works fine!
    But I wanted to populate another field, which is also a reference to the group (“information group”) so I added this field to the assignment lookup form, and this line “current.information_group = lookup.u_information_group;” to the assignment lookup rule. And finally I added this code to the Ajax assignment client script
    //Get the information_group ID and its display value and put then on the form
    var inf_group = item.getAttribute(“group”);
    var inf_group_label = item.getAttribute(“group_label”);
    if (inf_group_label != null && inf_group != null)
    g_form.setValue(‘information_group’, inf_group, inf_group_label);
    else
    g_form.setValue(‘information_group’, null);

    But it doesn’t work, and I don’t understand why…

    Hope you can help me!
    Thank you

    • Mark Stanger March 15, 2012 at 7:14 am - Reply

      Assignment rules only return a single user and group. If you want to populate any other piece of information then you’ll need to set it with a separate client script or template.

      • Pierre March 15, 2012 at 7:27 am - Reply

        Thanks for your response, I will search for another solution

  12. Mark Sandner July 16, 2012 at 1:32 pm - Reply

    Good news is that (according to thwiki) the Berlin release will address the following:
    â– Define when to run an assignment rule:
    â– On form change (Allows assignment rules to apply to unsaved changes on a form)
    â– On record insert
    â– On record update
    â– Option to replace existing values (including default values)

    The last item is good news …isn’t it?

    • Mark Stanger July 16, 2012 at 1:33 pm - Reply

      This is all good news. All of these items are things that I helped to design before I left ServiceNow. It will be great to have this built in once Berlin ships.

  13. David Field September 13, 2013 at 9:58 am - Reply

    Hi Mark,

    I’m a big fan of this bit of code, I’ve used it lots of times.

    I’m not a fan of using the data_lookup functionality available from Berlin onwards for this type of rule because the OOB Assignment Rules can be driven by much more criteria whilst being very simple to configure.

    Can you tell me if there is a way to call the Assignment Rules from the server side? I’d like to use the same rules for setting the assignment whether the form is displayed or a record is being inserted by a Business Rule

    • Mark Stanger September 13, 2013 at 4:23 pm - Reply

      They should work the same way, the only trick is that they won’t run unless the assignment fields are empty. I don’t know of a way to force them to run otherwise but you might be able to set up a business rule to perform a lookup against your custom table and do the same thing.

Leave A Comment