The Zurich release has arrived! Interested in new features and functionalities? Click here for more

Brent Sutton
Mega Sage

***** Article Updated to work with latest versions of ServiceNow *****

So you've got a nice shiny new portal and customers are loving the new Service Catalog. Then the inevitable happens, requests start coming in for issues that need to be treated as incidents.

 

In this post, I will show you how to create a custom ui action, to cancel the original RITM, copy variables, attachments and customer comments to a newly created Incident.

PLEASE NOTE: This solution should not be considered a substitute for addressing the root cause of why customers are selecting the incorrect request type. There are a number of ways to address this issue through portal design, catalog content and customer education. However, this UI Action will ease the pain for your Service Desk when these requests do come through.

Create Custom UI Action

  1. Navigate to System Definition > UI Actions.
  2. Click New.
  3. Complete UI Action with the following details.
  4. Click "Save" and you're done.

 

UI Action Fields

UI action fieldsValue
Name:Convert to Incident
Table:Requested Item [sc_req_item]
Form context menu:true (ticked)
Hint:Closes RITM and Creates Incident
Condition:(current.active == true) && gs.hasRole("itil")

 

ui_action_controls.png

 

UI Action Script

/* Construct RITM Links
-----------------------------------------------------------------------------------------------------------------------*/

var ritmTable = current.getTableName();
var ritmSysID = current.getUniqueValue();
var ritmNum = current.getValue('number');

//SERVICE PORTAL: construct a link to the original RITM for inclusion in the customer comments of the incident.
var spRITMLink = spLink(ritmTable,ritmSysID,ritmNum);

//PLATFORM: construct a link to the parent RITM that itil users can use to navigate from the newly created incident.
var platformRITMLink = platformLink(ritmTable,ritmSysID,ritmNum);

/* Construct comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
var comments = '[code]Incident created from ' + spRITMLink + '<br><br>';

comments += '<strong>Catalog Item Information:</strong><br>';
comments += '<table>';

//Query RITM variables, utilising the variable label and displayValue to build a table.
var vars = current.variables.getElements();
for (var i = 0; i < vars.length; i++){
	var question = vars[i].getQuestion();
	comments += '<tr><td>' + question.getLabel() + ':</td><td>' + question.getDisplayValue() + '</td></tr>';
}
comments += '</table>[/code]';

//include customer comments from the RITM (-1 returns all journal entries for specified journal field)
var ritmComments = current.comments.getJournalEntry(-1);

if (JSUtil.notNil(ritmComments)) {

	comments += '[code]<br><br><strong>Customer comments from ' + ritmNum + '</strong><br>[/code]';
	comments += ritmComments;
}

var workNotes = 'Link to [code]' + platformRITMLink + '[/code] from within ServiceNow.';

/* Ascertain the Assignment Group
-----------------------------------------------------------------------------------------------------------------------*/
var assignmentGroup = getAssignmentGroup(ritmSysID);

/* Create Incident
-----------------------------------------------------------------------------------------------------------------------*/
var inc = new GlideRecord("incident");

inc.caller_id = current.request.requested_for;
inc.assignment_group = assignmentGroup;
inc.short_description = current.short_description;
inc.cmdb_ci = current.cmdb_ci;
inc.impact = current.impact;
inc.urgency = current.urgency;
inc.priority = current.priority;
inc.company = current.company;
inc.sys_domain = current.sys_domain;
inc.comments = comments;
inc.work_notes = workNotes;
inc.parent = ritmSysID;

var incSysID = inc.insert();

var incTable = inc.getTableName();
var incNum = inc.getValue('number');

/* Copy attachments to Incident
-----------------------------------------------------------------------------------------------------------------------*/

//copy any RITM attachments to the newly created incident
GlideSysAttachment.copy(ritmTable, ritmSysID, incTable, incSysID);

/* Construct Incident Links
-----------------------------------------------------------------------------------------------------------------------*/

//SERVICE PORTAL: construct a link to the Incident for inclusion in the customer comments of the RITM.
var spIncLink = spLink(incTable,incSysID,incNum);

//PLATFORM: construct a link to the Incident that itil users can use to navigate from the parent RITM in platform.
var platformIncLink = platformLink(incTable,incSysID,incNum);

/* Update comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
current.comments = 'RITM converted to [code]' + spIncLink + '[/code]. Please use this reference from now on.';
current.work_notes = 'Link to [code]' + platformIncLink + '[/code] from within ServiceNow.';

/* Close RITM as "Closed Incomplete"
-----------------------------------------------------------------------------------------------------------------------*/
current.setValue('state', '4');
current.setValue('stage', 'Request Cancelled');
current.setValue('active', 'false');

var mySysID = current.update();

gs.addInfoMessage(gs.getMessage("Incident {0} created", incNum));

action.setRedirectURL(inc);
action.setReturnURL(current);

/* Link builders
-----------------------------------------------------------------------------------------------------------------------*/
function spLink(table,sysID,num){

	var link = '<a title="Service Portal Link" href="?id=ticket&table=' + table + '&sys_id=' + sysID + '">' + num + '</a>';

	return link;
}

function platformLink(table,sysID,num){

	var link = '<a title="Platform Link" href="' + table + '.do?sys_id=' + sysID + '">' + num + '</a>';

	return link;
}

/* Locate the last assignment group
-----------------------------------------------------------------------------------------------------------------------*/
function getAssignmentGroup(ritmSysID) {
	/* Return all active tasks relating to RITM ordered by newest task first i.e. last created ticket. */

	var tskGrp = new GlideRecord('sc_task');
	tskGrp.addActiveQuery();
	tskGrp.addQuery('request_item', ritmSysID);
	tskGrp.orderByDesc('number');
	tskGrp.orderByDesc('sys_created_on');
	tskGrp.query();

	var assignmentGroup = '';

	if(tskGrp.next()) {

		//set the assignment group to the last generated active task's assignment group
		assignmentGroup = tskGrp.getValue('assignment_group');
	}
	else {
		/* Default to the Service Desk if a assignment group cannot be found */
		//NOTE: This is a custom system property, containing the group sys_id for your service desk
		//You will need to create it in sys_poperties if you want to fall back to your service desk

		assignmentGroup = gs.getProperty('sc.service_desk');  
	}
	return assignmentGroup;
}

How to use

  1. Navigate to Service Catalog > Items.
  2. Select active RITM.
  3. Right Click on Header.
  4. Select Convert to Incident.
  5. You will be redirected to the new Incident.
ui_action_form.png
Comments
michaelzawacki
Mega Contributor

Has anyone tried this?   Any issues found?   We are looking into implementing this.


Brent Sutton
Mega Sage

Hi Michael, we've been using this UI Action in Helsinki for the past 4 months. We're currently preparing for upgrade to Kingston and it is testing without issues so far. Let me know how you get along with your implementation. Thanks, Brent


Mohammad10
Tera Contributor

I just tried it with New York patch 7, seems not working. 

Maverick E
Tera Guru

For anyone trying to accomplish this and it is not working, replace lines 33 - 47 with the following code:

var vars = current.variables.getElements();
for (var i = 0; i < vars.length; i++){
	var question = vars[i].getQuestion();
	gs.log(question.getLabel() + ":" + question.getValue());
	comments += '<tr><td>' + question.getLabel() + ':</td><td>' + question.getDisplayValue() + '</td></tr>';
}
Mohammad10
Tera Contributor

Thanks Maverick,

 

code start working now 🙂 

Brent Sutton
Mega Sage

Glad that this article is starting to get a bit of attention again. I'm going to refactor some of it soon but in the meantime, I'll update it with Maverick's fix so it works for new visitors to the article.

Brent Sutton
Mega Sage

Just updated the article with Maverick's fix. UI Action is now working with the latest version, at time of writing - Paris.

If the article was helpful then please hit the "helpful" button so it raises the article up in the community. It would also be worthwhile bookmarking or subscribing to the article as I'm looking to refactor some of the code in the next couple of weeks. Hope you enjoy, Brent

Cindy26
Tera Expert

What happens to the existing tasks that were generated from the workflow that started when the RITM was created? What happens to the original RITM and Request? Do they get canceled?

Brent Sutton
Mega Sage

Hi Cindy,

The original RITM gets set as "Closed Incomplete" with stage "Cancelled". If this is the only RITM that is associated to the Request then this is closed too.

The code that set the RITM state is below.

/* Close RITM as "Closed Incomplete"
-----------------------------------------------------------------------------------------------------------------------*/
current.setValue('state', '4');
current.setValue('stage', 'Request Cancelled');
current.setValue('active', 'false');

var mySysID = current.update();

Hope this helps,

Brent

P.S. If my suggestion helped then please mark as helpful so other community members can benefit from this information.

Cindy26
Tera Expert

What about the existing tasks? What state do they get set to?

Does it send any kind of message to the user such as "your request has been cancelled and Incident #123 has been created for you"? 

Brent Sutton
Mega Sage

Hi Cindy,

The existing catalog tasks are cancelled when the RITM is moved to closed incomplete. The UI action adds a link to the incident in the RITM's comments so the customer is informed that the RITM has been converted to an Incident.

/* Update comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
current.comments = 'RITM converted to [code]' + spIncLink + '[/code]. Please use this reference from now on.';
current.work_notes = 'Link to [code]' + platformIncLink + '[/code] from within ServiceNow.';

The newly created incident also links back to the original RITM if the fulfilment team needs to see the original request. This is available in the comments (Service Portal link), work notes (Platform link) and referenced in the parent field.

Brent

P.S. If this information helped then please mark as helpful so other community members can benefit from this information.

Cindy26
Tera Expert

I've created this in DEV and I'm having a couple issues:

1. As soon as you select 'convert to incident', it immediately cancels the existing RITM and tasks because the Incident is immediately saved after selecting this. How can I change this so that the incident form does not save/cancel the RITM until you actually save the new incident manually? Otherwise, if someone accidentally clicks "convert to incident" it is too late, because the RITM has already been canceled immediately. 

2. When clicking the link to the RITM (from incident) added to the additional comments field (from within the platform), I get an error "record not found". Same thing happens with the link to the Incident from the RITM  added to additional comments (from within the platform). If i click these links from within the service portal, they work correctly. (The link to the RITM added to work notes on the incident works correctly, as well as the link to the Incident added to the work notes on the RITM. It is only the additional comments links that aren't working within the platform). 

Brent Sutton
Mega Sage

Hi Cindy,

There are two different link types.

 

The link in the additional comments is for the customer and is intended to be opened from an email or directly in the Service Portal.

The link on the work notes is only visible to the fulfilment teams and is intended for use in the platform.

 

The Ui action is designed to create the incident and close the RITM in one action. It won't accommodate a delayed save on the incident side as the action is initiated and completed from the RITM.

 

Brent

Cindy26
Tera Expert

We have a similar action we are using to convert an Incident to a Request and that one does not cancel the Incident until the request is manually saved. I'm not a developer and didn't write this script so I don't know how this truly works, but here is that script. What would I need to change in the script above in order to have the same result here?

 

Brent Sutton
Mega Sage

Hi Cindy,

The UI Action you sent a screenshot of renders a separate UI page, "catalog_item_list_v2", which I assume requires input from the user before proceeding with saving the record.

You could copy my UI action code and use it as the basis for your own version. You'll need to create a separate UI Page and trigger its display from your UI Action. I won't be adding it to this article.

Hope this helps,

Brent.

Jamie52
Mega Expert

Hi All,

Can anyone tell me why the links in the Comments and Work Notes aren't working for me.

find_real_file.png

Brent Sutton
Mega Sage

Your ServiceNow instance probably restricts the use of code tags in journal fields. You can control this behaviour using the glide.ui.security.allow_codetag property. More information can be found here - Restrict the CODE tag in journal fields 

Andrew Meza
Tera Expert

Hey @Brent Sutton, just curious if you have a solution for this but the opposite. I have implemented the Request to Incident, and I love the way it works. Wondering if it were possible for Incidents to be converted to Request.

Brent Sutton
Mega Sage

Hi @Andrew Meza, technically you could build a UI Action to convert an incident to a request, but it isn't something I would personally recommend. Requests have multiple layers to contend with i.e. Request, RITM, and catalog tasks. They also differ in the information they require to fulfil a service on a per catalog item basis.

 

If you go down this route, you'll want to create a "generic" catalog item to accept the converted incident and generate an RITM and associated Request. The RITM flow should then kick in to create any required catalog tasks. You may be able to use my article's UI action as a starting point, but you'll need to extend for your use case. Hopefully, this helped.

 

Brent

 

P.S. If the article was useful then please bookmark and mark as helpful. This improves the articles ranking and ensures that other community members find the content more easily.

 

EricG
Kilo Sage

This is great.  In Tokyo, I'm using your original script.  It appears to be working.

however, I can't get values like Category/Subcategory, etc. to copy over.

 

/* Create Incident
-----------------------------------------------------------------------------------------------------------------------*/
var inc = new GlideRecord("incident");

inc.caller_id = current.request.requested_for;
inc.assignment_group = assignmentGroup;

inc.u_entity = current.u_entity;//reference to custom table
inc.contact_type = current.u_contact_type;
inc.location = current.location;//select reference to cm_location
inc.category = current.category;//select choice
inc.subcategory = current.u_choice_2;//select choice

inc.short_description = current.short_description;
inc.description = current.description;

any reason why this wouldn't copy?

Brent Sutton
Mega Sage

Hi @EricG,

 

RITMs don't natively have category or subcategory fields on the table. If you have those fields then it is probably a customisation.

 

Let's assume it is a customisation, then I would look at Your RITM category and subcategory values and see if there is a corresponding equivalent on the incident table. You may have used the same display values but under the hood the actual values may be different.

BrentSutton_0-1681158661226.png

 

I'm also not sure what you are trying to do in this line?

 

inc.subcategory = current.u_choice_2;//select choice

 

 

Are you trying to set it to a static category and subcategory (choice 2 of your subcategory)? If so, you could just use the value to set the incident fields

 

Example:

inc.category = "inquiry"; // I actually prefer this syntax - inc.setValue("inquiry");
inc.subcategory = "email";

 

Let me know if this worked for you,

 

Brent

 

P.S. Please remember to bookmark this article and/or mark as helpful if you got some value from this post.

BrentSutton_1-1681159242760.png

 

jotavio
Tera Explorer

Hi @Brent Sutton !

 

Thank you for this content you created.

 

I tried replicating the code to our environment but I got an error when I run the UI button saying "JSUtil undefined, maybe missing global qualifier" and the ticket is never created.

 

Do you know what it could be?

Brent Sutton
Mega Sage

Hi @jotavio,

 

JSUtil is an OOTB script include (in Global scope) provided by ServiceNow. You can review the code by looking at the following URL on your instance: -

 

https://<your_instance_name_here>.service-now.com/sys_script_include.do?sys_id=8d5571660a0a0b5000fc97b926f7f750

 

Are you trying to create the UI Action in a different application scope i.e. not global? That would be the only reason I can think of that would produce your error (or JSUtil script include isn't present in your instance). 

 

Either way, its not a problem. If you can't reach JSUtil then just do a simple check to ensure there is comments to add. Something like the below:

 

 

if (ritmComments != null || typeof ritmComments != 'undefined') {

	comments += '[code]<br><br><strong>Customer comments from ' + ritmNum + '</strong><br>[/code]';
	comments += ritmComments;
}

 

 

Let me know if the above worked for you.

 

Brent

P.S. Don't forget to bookmark the article and hit Kudos if this helped you.

Gemma4
Mega Sage

HI @Brent Sutton 

This is really helpful! I'm on Utah and have this nearly working but the links in the comments don't open up. Is there something I did wrong. I verified the property mentioned above- glide.ui.security.allow_codetag  is true and below is the code used in the ui action

any ideas or suggestions for me to try? 

 

/* Construct RITM Links
-----------------------------------------------------------------------------------------------------------------------*/
 
var ritmTable = current.getTableName();
var ritmSysID = current.getUniqueValue();
var ritmNum = current.getValue('number');
 
//SERVICE PORTAL: construct a link to the original RITM for inclusion in the customer comments of the incident.
var spRITMLink = spLink(ritmTable,ritmSysID,ritmNum);
 
//PLATFORM: construct a link to the parent RITM that itil users can use to navigate from the newly created incident.
var platformRITMLink = platformLink(ritmTable,ritmSysID,ritmNum);
 
/* Construct comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
var comments = '[code]Incident created from ' + spRITMLink + '<br><br>';
 
comments += '<strong>Catalog Item Information:</strong><br>';
comments += '<table>';
 
//Query RITM variables, utilising the variable label and displayValue to build a table.
var vars = current.variables.getElements();
for (var i = 0; i < vars.length; i++){
var question = vars[i].getQuestion();
comments += '<tr><td>' + question.getLabel() + ':</td><td>' + question.getDisplayValue() + '</td></tr>';
}
comments += '</table>[/code]';
 
//include customer comments from the RITM (-1 returns all journal entries for specified journal field)
var ritmComments = current.comments.getJournalEntry(-1);
 
if (JSUtil.notNil(ritmComments)) {
 
comments += '[code]<br><br><strong>Customer comments from ' + ritmNum + '</strong><br>[/code]';
comments += ritmComments;
}
 
var workNotes = 'Link to [code]' + platformRITMLink + '[/code] from within ServiceNow.';
 
/* Ascertain the Assignment Group
-----------------------------------------------------------------------------------------------------------------------*/
var assignmentGroup = getAssignmentGroup(ritmSysID);
 
/* Create Incident
-----------------------------------------------------------------------------------------------------------------------*/
var inc = new GlideRecord("incident");
 
inc.caller_id = current.request.requested_for;
inc.assignment_group = assignmentGroup;
inc.short_description = current.short_description;
inc.cmdb_ci = current.cmdb_ci;
inc.impact = current.impact;
inc.urgency = current.urgency;
inc.priority = current.priority;
inc.company = current.company;
inc.sys_domain = current.sys_domain;
inc.comments = comments;
inc.work_notes = workNotes;
inc.parent = ritmSysID;
 
var incSysID = inc.insert();
 
var incTable = inc.getTableName();
var incNum = inc.getValue('number');
 
/* Copy attachments to Incident
-----------------------------------------------------------------------------------------------------------------------*/
 
//copy any RITM attachments to the newly created incident
GlideSysAttachment.copy(ritmTable, ritmSysID, incTable, incSysID);
 
/* Construct Incident Links
-----------------------------------------------------------------------------------------------------------------------*/
 
//SERVICE PORTAL: construct a link to the Incident for inclusion in the customer comments of the RITM.
var spIncLink = spLink(incTable,incSysID,incNum);
 
//PLATFORM: construct a link to the Incident that itil users can use to navigate from the parent RITM in platform.
var platformIncLink = platformLink(incTable,incSysID,incNum);
 
/* Update comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
current.comments = 'RITM converted to [code]' + spIncLink + '[/code]. Please use this reference from now on.';
current.work_notes = 'Link to [code]' + platformIncLink + '[/code] from within ServiceNow.';
 
/* Close RITM as "Closed Incomplete"
-----------------------------------------------------------------------------------------------------------------------*/
current.setValue('state', '4');
current.setValue('stage', 'Request Cancelled');
current.setValue('active', 'false');
 
var mySysID = current.update();
 
gs.addInfoMessage(gs.getMessage("Incident {0} created", incNum));
 
action.setRedirectURL(inc);
action.setReturnURL(current);
 
/* Link builders
-----------------------------------------------------------------------------------------------------------------------*/
function spLink(table,sysID,num){
 
var link = '<a title="Service Portal Link" href="?id=ticket&table=' + table + '&sys_id=' + sysID + '">' + num + '</a>';
 
return link;
}
 
function platformLink(table,sysID,num){
 
var link = '<a title="Platform Link" href="' + table + '.do?sys_id=' + sysID + '">' + num + '</a>';
 
return link;
}
 
/* Locate the last assignment group
-----------------------------------------------------------------------------------------------------------------------*/
function getAssignmentGroup(ritmSysID) {
/* Return all active tasks relating to RITM ordered by newest task first i.e. last created ticket. */
 
var tskGrp = new GlideRecord('sc_task');
tskGrp.addActiveQuery();
tskGrp.addQuery('request_item', ritmSysID);
tskGrp.orderByDesc('number');
tskGrp.orderByDesc('sys_created_on');
tskGrp.query();
 
var assignmentGroup = '';
 
if(tskGrp.next()) {
 
//set the assignment group to the last generated active task's assignment group
assignmentGroup = tskGrp.getValue('assignment_group');
}
else {
/* Default to the Service Desk if a assignment group cannot be found */
//NOTE: This is a custom system property, containing the group sys_id for your service desk
//You will need to create it in sys_poperties if you want to fall back to your service desk
 
assignmentGroup = gs.getProperty('sc.service_desk');  
}
return assignmentGroup;
}
Brent Sutton
Mega Sage

Hey @Gemma4,

 

The Service Portal Link that is inserted into the additional comments field is intended to be clicked on by users from the portal. It won't resolve correctly if clicked from the platform view.

There is a second platform link in the work notes that has the correct construct for support staff to quickly navigate between the INC and originating RITM. 

I just tested it in ServiceNow Vancouver, and it seems to be working okay (been a while since I last looked at it).

 

Let me know if it now works for you.

 

Brent

P.S. Don't forget to bookmark the article and hit Kudos if this helped you.

Gemma4
Mega Sage

Thank you @Brent Sutton I appreciate that insight. I tested that further and when I select the work notes link from the platform it does take me directly to the incident. While testing, I impersonated a user with ITIL access and tried the convert to incident and was directed to a user form instead of the incident form opening. Any ideas if this is a permission issue or change to make? 

Impersonate.png

Gemma4
Mega Sage

I think the issue could be because of the business rule sc_req_item comment events, but I'm not sure why the error is not constant in all instances? 

 

https://www.servicenow.com/community/sam-forum/pop-up-came-up-whenever-the-comments-posted-on-the-ri...

Brent Sutton
Mega Sage

Hey @Gemma4, I just tested it in my personal developer instance as an itil user and it redirected to the incident correctly. These line items in the code set the redirect and return URLS:

action.setRedirectURL(inc);
action.setReturnURL(current);

There must be something in your instance that is intercepting the redirect. Unfortunately I can't replicate the issue on my side.

Gemma4
Mega Sage

Thanks so much @Brent Sutton for the feedback. I don't believe it is the business rule you mentioned Incident null created. I set the business rule inactive and still received the same error. I verified the user had ITIL access and even logged in as the user...any other suggestions? 

thanks

Brent Sutton
Mega Sage

Hi @Gemma4, I don't think I mentioned anything about a business rule? I just said that I can't replicate your issue.

From your earlier screenshot I can see that an Incident was created. Were all the details also correctly updated on the RITM i.e. comments, work_notes, state, stage and active?

dani m
Tera Contributor

@Brent Sutton 


I think I have spent more time reading this post than any other in the community, kudos, you are a rockstar.

 

I am so new that I am almost embarrassed to ask, but I have yet to find a solution, so here goes...

I am trying to create a couple of UI actions to convert a RITM to an Enhancement or Defect like you find OOTB for the Incident table.  Do you think that with the appropriate tweaking to the tables in your script, this would be doable?  

Use case: is to prevent rework, and allow service desk fulfillers to convert these requests so they can get into the hands of our dev teams in a timely manner.

 

Cheers and thanks in advance for your time,
Dani

Brent Sutton
Mega Sage

Hi @dani m,

 

The script could definitely be amended to create an enhancement or defect. The key change would be this part of the script:

 

 

/* Create Incident
-----------------------------------------------------------------------------------------------------------------------*/
var inc = new GlideRecord("incident");

inc.caller_id = current.request.requested_for;
inc.assignment_group = assignmentGroup;
inc.short_description = current.short_description;
inc.cmdb_ci = current.cmdb_ci;
inc.impact = current.impact;
inc.urgency = current.urgency;
inc.priority = current.priority;
inc.company = current.company;
inc.sys_domain = current.sys_domain;
inc.comments = comments;
inc.work_notes = workNotes;
inc.parent = ritmSysID;

var incSysID = inc.insert();

var incTable = inc.getTableName();
var incNum = inc.getValue('number');

 

 

Just change the GlideRecord to either Defect [rm_defect] or Enhancement [rm_enhancement] and remap which fields on those tables that you wish to populate the RITM data i.e.

 

 

/* Create Defect
-----------------------------------------------------------------------------------------------------------------------*/
var defect = new GlideRecord("rm_defect");

defect.assignment_group = assignmentGroup;
defect.short_description = current.short_description;
defect.cmdb_ci = current.cmdb_ci;
defect.comments = comments;
defect.work_notes = workNotes;
defect.parent = ritmSysID;

var defectSysID = defect.insert();

var defectTable = defect.getTableName();
var defectNum = defect.getValue('number');

 

 

 

P.S. change any references in the UI action to the new variable names in my example i.e. inc==>defect, incTable==>defectTable, incNum==>defectNum. These variables are used in the action.setRedirectURL and to compose the portal and platform url links that are added to comments and worknotes.

 

If you are thinking about making multiple UI actions, for different tables, then you may want to move some of the script logic into a script include for reuse between them.

 

Hope this helps.

 

Brent

Lisa Goldman
Kilo Sage

Hello @Brent Sutton 

The end-users are constantly selecting the wrong type of request. Your custom UI actions are an enormous help in resolving this issue.  I need your guidance on how I can removed/modify the work note link as how in the screenshot below.  I sincerely thank you for your time and effort.

 

LisaGoldman_2-1710867759487.png

 

Or changing the wording, because we don't use Quantity or Product Name.

LisaGoldman_1-1710867074972.png

 

Brent Sutton
Mega Sage

Hi @Lisa Goldman ,

 

If you don't want the RITM variables in the customer comments then comment out, or remove them. from this section of the script: -

 

/* Construct comments and work notes
-----------------------------------------------------------------------------------------------------------------------*/
var comments = '[code]Incident created from ' + spRITMLink + '<br><br>';

/*------------------------------------Removing variables from the comments----------------------------------------------
comments += '<strong>Catalog Item Information:</strong><br>';
comments += '<table>';

//Query RITM variables, utilising the variable label and displayValue to build a table.
var vars = current.variables.getElements();
for (var i = 0; i < vars.length; i++){
	var question = vars[i].getQuestion();
	comments += '<tr><td>' + question.getLabel() + ':</td><td>' + question.getDisplayValue() + '</td></tr>';
}
comments += '</table>[/code]';
---------------------------------------End of commenting out-------------------------------------------------------------*/

//include customer comments from the RITM (-1 returns all journal entries for specified journal field)
var ritmComments = current.comments.getJournalEntry(-1);

if (JSUtil.notNil(ritmComments)) {

	comments += '[code]<br><br><strong>Customer comments from ' + ritmNum + '</strong><br>[/code]';
	comments += ritmComments;
}

In the above example I have just left in the RITM link and RITM journal entry history to be added to the comments in the newly created incident.

You could put in some logic to filter out certain variable names from the comments but this may vary from catalog item to catalog item.

 

Let me know if the above worked for you.

Brent

P.S. Don't forget to add Kudos for replies if they helped resolve your question. It helps others find this information.

Lisa Goldman
Kilo Sage

Hello @Brent Sutton 

After thorough testing, I can confirm that the updated code is performing flawlessly. 

Your outstanding work is greatly appreciated, and your  willingness to share it with the community is commendable.  Thank you!

Brent Sutton
Mega Sage

Thank you for the kind words @Lisa Goldman. Glad it worked for you. 

abc_12
Tera Contributor

HI @Brent Sutton 

 

According to your code, it is converting to an incident, however I would like to include a confirmation popup before it does so. Could you please suggest me the solution for this?

Lisa Goldman
Kilo Sage

Hello Brent,

Thank you very much for implementing such an excellent solution. We have been using your custom UI Action for some time, and it has been working fantastically.

 

I have been searching online for a way to convert a Service Request to a Change Request but couldn’t find a good example. I know ServiceNow already provides an out-of-the-box UI action on the sc_req_item table to create a Change Request, but it is not as effective as yours code.

 

I would like to modify your code to convert a Service Request to a Change Request, but I am struggling to get it to work because my JavaScript is still at a beginner level.  

Brent Sutton
Mega Sage

Hi @Lisa Goldman, you could certainly use parts of my code to convert a RITM to a change. I would take a copy of the ServiceNow OOTB UI action as a base and then extend with desired elements from my code. Unfortunately, I don't have a ready made one I can share but it is definitely doable.

Thanks, Brent

Lisa Goldman
Kilo Sage

Thank you for the offer Brent. Over the past few days, I have been working on adapting your code to transfer all variables from RITM to change request work notes and establish a link between the two modules for easy navigation. However, I'm still struggling to make it work.

 

If I post a question on the SN community, could you please take a look at the code and provide guidance/suggestions on how to make it works.

DJayBlackout
Tera Explorer

Just want to say a massive thank you @Brent Sutton this still works in 2025 on Xanadu.

 

For those who have CSM and want this to work it does.

Requests that have been created from a Case, have the Case listed as the parent of the Request, we simply then dot walked from the Request to the Case and updated the Incident field on the Case with the newly created Incident from this UI Action.

Script below inserted at line 86

/* Associate Incident to Case
-----------------------------------------------------------------------------------------------------------------------*/

var caseGr = current.request.parent.getRefRecord();
caseGr.incident = incSysID;
caseGr.update();
Brent Sutton
Mega Sage

Hi @DJayBlackout, I'm glad that this article is still helping the community. The last time I tested this UI Action was back in Vancouver release so its good to hear that its still working in Xanadu!

Thanks, Brent

Hafila Hatta
Tera Guru

Hi! i came across this post and was wondering, if it's possible to restrict this functionality for a specific catalog item?

Brent Sutton
Mega Sage

Hi @Hafila Hatta, you could definitely restrict this to a specific catalog item. The UI action is created on the Requested Item [sc_req_item] table which has a field called Item [cat_item]. You just need to set the UI Action condition to be specific to the catalog item that you want to restrict it to.

 

Example:

(current.active == true) && gs.hasRole("itil") && (current.cat_item === '<your catalog item sys_id here>')

 

Let me know if this worked for you.

 

Brent 

Version history
Last update:
‎12-12-2017 04:43 PM
Updated by: