A

few months ago I wrote about copying change requests using a UI action. While that method works great, it does require you to specify each and every field and value that you want to populate into the new change request. If you’ve got a lot of fields to copy over then you might end up with a pretty big script and a lot of items to copy over. You also need to be aware of any new fields that get added after you create the script and make sure that they get copied if necessary.

The following method works in much the same way, but it copies by performing an insert against the current record (rather than starting from a brand new change record and supplying each value). Because of this, you’re concerned about overriding any of the values (such as start and end dates) that you DON’T want to be copied over from the record you are copying. This method works better if you know you want to copy over all (or the majority) of the field values from a given change.

Copy Change UI action
Name: Copy change
Form button: True
Table: Change Request
Condition: gs.hasRole(“itil”) && current.isValidRecord()
Script:

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(); //Get 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;
    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) {
    //Get the task record being copied
    var tskRec = new GlideRecord('task');
    if(tskRec.get(chgID)){
        //Copy over the affected CI list
        var cis = new GlideRecord('task_ci');
        cis.addQuery('task', chgID);
                cis.addNullQuery('u_ci_group'); //Added to ensure that copying does not duplicate Group CIs
        if(gs.getProperty('change.conflict.mode')=='advanced' && tskRec.cmdb_ci!=''){
            //Prevent duplicate CI from being added
            cis.addQuery('ci_item', '!=', tskRec.cmdb_ci.toString());
        }
        cis.query();
        while(cis.next()){
            var newCI = cis;
            newCI.task = current.sys_id;
            cis.insert();
        }
    }
}

One other method for copying a change (or any other ticket) is to reference the record to copy and copy from the referenced record. You could use the script below to copy a change that is pulled from a reference field on any form. Just provide the name of the field to grab the change from in line 3.

Copy change UI action (For copying a referenced Change Request

//Get the current sys_id value for querying
//Provide the name of the reference field to copy change from
var chgID = current.your_change_reference_field.toString();
var rec = new GlideRecord('change_request');
rec.get(chgID);
copyChange();

function copyChange() {
    //Initialize new change for insertion
    var newChange = rec;
    newChange.number = getNextObjNumberPadded(); //Get 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;
    rec.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(rec);
}

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 = rec.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) {
    //Get the task record being copied
    var tskRec = new GlideRecord('task');
    if(tskRec.get(chgID)){
        //Copy over the affected CI list
        var cis = new GlideRecord('task_ci');
        cis.addQuery('task', chgID);
                cis.addNullQuery('u_ci_group'); //Added to ensure that copying does not duplicate Group CIs
        if(gs.getProperty('change.conflict.mode')=='advanced' && tskRec.cmdb_ci!=''){
            //Prevent duplicate CI from being added
            cis.addQuery('ci_item', '!=', tskRec.cmdb_ci.toString());
        }
        cis.query();
       
        while(cis.next()){
            var newCI = cis;
            newCI.task =
            rec.sys_id;
            cis.insert();
        }
    }
}