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
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.
—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…
Name: Assignment lookup rule
Table: Incident
Match conditions: All
Execution order: 10
Group/User: empty
Condition: Assignment Group is empty
Script:
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…
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:
- Download: Assignment Rule Lookup
- Supporting Documentation: Installing an update set on your instance
Comments
Posted On
Jul 13, 2010Posted By
MatthewMark,
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
Posted On
Jul 14, 2010Posted By
Mark StangerI 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.
Posted On
Jul 14, 2010Posted By
MatthewMark,
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.
Posted On
Jul 14, 2010Posted By
Mark StangerI 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.
Posted On
Jul 16, 2010Posted By
Mark StangerMatthew,
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.
Posted On
Jul 27, 2010Posted By
Jim UominiThis 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.
Posted On
Jul 27, 2010Posted By
Mark StangerThat’s great to hear Jim! Thanks for commenting.
Posted On
Aug 05, 2010Posted By
Mark StangerI 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.
Posted On
Jan 11, 2011Posted By
Tony FugereThis 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.
Posted On
Jan 12, 2011Posted By
Mark StangerWow. 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.
Posted On
Jan 18, 2011Posted By
AjayHI 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
Posted On
Jan 18, 2011Posted By
Mark StangerThat 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…
...or...
current.assignment_group.setDisplayValue('Assignment Group Name');
Posted On
Jan 18, 2011Posted By
AjayThank 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
Posted On
Jul 27, 2011Posted By
maxHi 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,
Posted On
Jul 28, 2011Posted By
Mark StangerBased on this list it looks like you’re missing the actual assignment rule for the change request table.
Posted On
Jul 28, 2011Posted By
maxi 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
Posted On
Aug 10, 2011Posted By
CeulHi 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,
Posted On
Aug 10, 2011Posted By
Mark StangerThat’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.
Posted On
Aug 12, 2011Posted By
CeulThanks a lot Mark it works fine !
Posted On
Aug 12, 2011Posted By
MirhusI’ve implemented assignment lookup on incident. It work great ! thanks.
Posted On
Aug 14, 2011Posted By
maxHi Mark,
It works now.
I missed a little thing.
Much appreciate it
Max