Can you clone/copy a change request?

jmbrake
Kilo Expert

Is there a way to take a past change request either approved, cancelled or in waiting approval state and copy it.   From there change the dates and submit it as new?

1 ACCEPTED SOLUTION

Hi Joan,



It is actually really easy. What you need to do is create a new UI Action(you define the type - button, cotext menu, etc.), as:


1. select the table: change_request


2. set the UI Action as Active and select when to show - on insert, update, etc.


3. have the script which creates a new record and carries over all attributes/fields that you wish (please see it attached)


And that should be it.



I hope this would help you. If so, please mark it up.


Good luck in creating!


View solution in original post

33 REPLIES 33

I am nearly there but need one more piece of information.   Thanks for your help on this and sorry if I am taking up too much of your time.



Below is the script I am using.   The only thing it is not doing that I need it to do is to change the Approval field to "Not Yet Requested".   When you copy from a change control that was already approved, it leave the Approval field as approved.   I do not know the code to change it to "Not Yet Requested"





copyChange();


function copyChange() {


//Get the current sys_id value for querying


var chgID = current.sys_id.toString();


//Initialize new change for insertion


var newChange = current;


newChange.number = getNextObjNumberPadded(); //Gethttps://kwiktripdev.service-now.com/images/icons/full_screen.gifx next change number


newChange.requested_by_date = 'NULL';


newChange.start_date = 'NULL';


newChange.end_date = 'NULL';


newChange.calendar_duration = 'NULL';


newChange.opened_at = current.opened_at;


newChange.opened_by = current.opened_by;


newChange.sys_created_on = current.sys_created_on;


newChange.sys_created_by = current.sys_created_by;


newChange.state = -16;


current.insert();




//Copy attachments for this change


if (typeof GlideSysAttachment != 'undefined')


    GlideSysAttachment.copy('change_request', chgID, 'change_request', newChange.sys_id);


else


    Packages.com.glide.ui.SysAttachment.copy('change_request', chgID, 'change_request', newChange.sys_id);




//Copy associated tasks and CIs


copyTask(chgID);


copyCI(chgID);


gs.addInfoMessage('Change ticket ' + newChange.number + ' created.');


action.setRedirectURL(newChange);


}




function copyTask(chgID) {


//Find the current change tasks and copy them


var tasks = new GlideRecord('change_task');


tasks.addQuery('change_request', chgID);


tasks.query();


while(tasks.next()){


var taskID = tasks.sys_id.toString();


var newTask = tasks;


if (typeof GlideNumberManager != 'undefined')


    newTask.number = GlideNumberManager.getNumber('change_task');


else


    newTask.number = Packages.com.glide.db.NumberManager.getNumber('change_task'); //Get next change task number


newTask.change_request = current.sys_id;


tasks.insert();




//Copy attachments for this task


if (typeof GlideSysAttachment != 'undefined')


    GlideSysAttachment.copy('change_task', taskID, 'change_task', tasks.sys_id);


else


    Packages.com.glide.ui.SysAttachment.copy('change_task', taskID, 'change_task', tasks.sys_id);


}


}




function copyCI(chgID) {


//Copy over the affected CI list


var cis = new GlideRecord('task_ci');


cis.addQuery('task', chgID);


cis.query();


while(cis.next()){


var newCI = cis;


newCI.task = current.sys_id;


cis.insert();


}


}


Mwatkins
ServiceNow Employee
ServiceNow Employee

DANGER DANGER DANGER


Besides having some logical flaws that attach the new Change Tasks to the old Change Request, the code posted above with "copyChange()" method is vulnerable to run away query if the chgID variable is not valid. This ended up causing an outage in a customer instance because millions of task_ci records were attached to a single Change Task. When the Change Task was deleted the event table was flooded and caused an effective outage since no emails were sent out for over 3 hours.



I certainly do not fault Joan for this since, as she mentioned herself in this thread, she had only been scripting for a few days at the time and was only sharing her learning with the community.   As with all code found in the community there is no testing or guarantee of functionality. Please carefully test and evaluate all custom code that is put into your instance.



The code would not be vulnerable to this issue if, before using a variable, the code was to ensure that the variable had a value. See "Verify values exist before using them" in the wiki page: Coding Best Practices - ServiceNow Wiki


Hi Joan,



It is actually really easy. What you need to do is create a new UI Action(you define the type - button, cotext menu, etc.), as:


1. select the table: change_request


2. set the UI Action as Active and select when to show - on insert, update, etc.


3. have the script which creates a new record and carries over all attributes/fields that you wish (please see it attached)


And that should be it.



I hope this would help you. If so, please mark it up.


Good luck in creating!


Hi all,



Thanks for script, I noticed that the script doesn't copy the custom questions we have built into our change request, can you point me in the right direction of being able to script this?



Apologies I am new to scripting, I attended a 3 day Service Now Admin course 12 months ago, but have done little admin work, other than building a Service Catalog, when it comes to scripting I am very much a novice.



Mark


Hello Mark,


The custom fields, which I assume will have these questions as labels, have a specific field name which would start with "u_".   You can view these by right-clicking the label of the field and look to see what follows the last menu item with   "Show - [field name]".   When you want to clone these fields, you would use the same format that Dimitar had on line 7 of his script:



change.u_change_overview = current.u_change_overview



This is what tells the system to make the field on the new record to have the same value as the corresponding field on the original record.



I hope that helps.