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

Mwatkins
ServiceNow Employee
ServiceNow Employee

Hi Paul,


If I understand correctly you are trying to allow a kind of form edit functionality where your end user could tweak the new cloned record before it is cloned. So, for example, suppose a user wants to clone an incident. They want to get all the field values cloned except for the short description. That one they want to change before they click the "Clone" button. Right?



There isn't an out-of-box way to open a new form (i.e. an unsubmitted record) that comes pre-populated with the values from a cloned record. However, you could achieve your business goal by instructing the user to just make their alterations on the original records form before clicking "Clone". Clicking "Clone" will not save the alterations to the original record but it will include the alterations in the cloned record. This is because, in the UI Action context, the "current" variable will refer to the values of the record that were submitted with the form when the "Clone" button was clicked. As long as the code doesn't do a current.update() no change will be propagated to the original record.



Regards, Matthew


Matthew, thanks for heads up about the limitations and the workaround.   We decided to go with a templated Record Producer we call from a UI Action on an Incident identified as having a "similar enough" short description.   Its actually provided a little more flexibility.   So far, its been performing nicely.



Best,


~Paul


Hi Dimitar, many thanks for this - has proved very handy indeed.



I have a question though, any idea why when using the new custom UI Action, the CHG number generated is skipping one from the last i.e. if CHG0010211 is the last change in the system, and I use the UI Action on it to copy I am observing that the next CHG number is CHG0010213 instead of CHG0010212!?



Not really a problem would just like to understand why?



Many thanks!


Daniel


Hi again, quick follow-up question but what is the easiest way for me to hide the form context menu UI Actions of 'Insert' and 'Insert & Stay' (Global actions) given that I just want my new custom UI Action to be available on the CHG form now (but Insert actions to show for other forms)



Hopefully is a simple one! Thanks again. Daniel


anuguajayreddy
Tera Contributor

We have created a UI Action, and called script include to have more features like coping attachments if required



function doAttachments() {


     


      if (!g_form.mandatoryCheck() || g_form.mandatoryCheck() == false) {


            return false;


      }


     


    var do_attachments = false;


   


    var gr = new GlideRecord('sys_attachment');


    gr.addQuery('table_sys_id', gel('sys_uniqueValue').value);


    gr.query();


   


    if (gr.next()) {


          do_attachments = confirm('Would you like the attachment(s) to be copied?');


    }



    var ga = new GlideAjax('CopyChgAJAX');


    ga.addParam('sysparm_name', 'copyChange');


    ga.addParam('sysparm_sys_id', g_form.getUniqueValue());


    ga.addParam('sysparm_do_attachments', do_attachments);


    ga.getXML(parseAnswer);


   


    function parseAnswer(response)


    {


          var answer = response.responseXML.documentElement.getAttribute('answer');


           


          self.location = "change_request.do?sys_id=" + answer;



         


    }


}



Below is the script include to call, which will fulfill the complete copy activity.



var CopyChgAJAX = Class.create();



CopyChgAJAX.prototype = Object.extendsObject(AbstractAjaxProcessor, {


   


    copyChange:   function() {



          var sys_id = this.getParameter('sysparm_sys_id');


          var do_attachments = this.getParameter('sysparm_do_attachments');


         


          var grCHG = new GlideRecord('change_request');


          grCHG.get(sys_id);


         


         


          var newRec = new GlideRecord('change_request');


          newRec.initialize();


         


          newRec.requested_by = grCHG.requested_by; //


          newRec.u_requested_for = grCHG.u_requested_for; //


          newRec.u_source_of_change = grCHG.u_source_of_change; //


          newRec.u_change_scale = grCHG.u_change_scale; //


          newRec.type = grCHG.type; //


          newRec.short_description = grCHG.short_description; //


          newRec.cmdb_ci = grCHG.cmdb_ci; //


          newRec.u_business_criticality = grCHG.u_business_criticality;


          newRec.u_business_service = grCHG.u_business_service; //


          newRec.u_business_approver = grCHG.u_business_approver; //


          newRec.u_technical_service = grCHG.u_technical_service; //


          newRec.u_project_release = grCHG.u_project_release; //


          newRec.u_informational = grCHG.u_informational; //


          newRec.state = 1;


          newRec.impact = grCHG.impact; //


          newRec.risk = grCHG.risk; //


          newRec.priority = grCHG.priority; //


          newRec.u_region_glist = grCHG.u_region_glist; //


          newRec.u_approval_workflow = grCHG.u_approval_workflow; //


          newRec.u_vendor = grCHG.u_vendor; //


          newRec.assignment_group = grCHG.assignment_group; //


          newRec.assigned_to = grCHG.assigned_to; //


          newRec.u_approved = grCHG.u_approved; //


          newRec.description = grCHG.description; //


          newRec.u_src_problem = grCHG.u_src_problem; //


          newRec.u_src_incident = grCHG.u_src_incident; //


          newRec.u_parent_change = grCHG.u_parent_change; //


          newRec.u_service_impact = grCHG.u_service_impact; //


          newRec.u_business_user_impact = grCHG.u_business_user_impact; //


          newRec.u_service_availablity = grCHG.u_service_availablity; //


          newRec.u_duration_of_implementation = grCHG.u_duration_of_implementation; //


          newRec.u_technology_maturity = grCHG.u_technology_maturity; //


          newRec.rfc = grCHG.rfc;


          newRec.u_backout_remediation_capabili = grCHG.u_backout_remediation_capabili; //


          newRec.u_change_conflict = grCHG.u_change_conflict; //


          newRec.u_knowledge_impacted_ci = grCHG.u_knowledge_impacted_ci; //


          newRec.backout_plan = grCHG.backout_plan; //


          newRec.test_plan = grCHG.test_plan; //


          newRec.u_validation_plan = grCHG.u_validation_plan; //


          newRec.implementation_plan = grCHG.implementation_plan; //


          newRec.u_reason_for_change = grCHG.u_reason_for_change; //


          newRec.u_pir_required = grCHG.u_pir_required;


          newRec.u_pir_owner = grCHG.u_pir_owner;


          newRec.u_pir_type = grCHG.u_pir_type;


          newRec.u_pir_meeting_attendees = grCHG.u_pir_meeting_attendees;


          newRec.u_reason_for_pir = grCHG.u_reason_for_pir;


          newRec.u_change_successful = grCHG.u_change_successful;


          newRec.u_customer_satisfied = grCHG.u_customer_satisfied;


          newRec.u_unauthorized_change = grCHG.u_unauthorized_change;


          newRec.u_expedited_change = grCHG.u_expedited_change;


          newRec.u_rescheduled_change = grCHG.u_rescheduled_change;


          newRec.u_change_type_modified = grCHG.u_change_type_modified;


          newRec.u_change_scale_modified = grCHG.u_change_scale_modified;


          newRec.u_tasks_past_due = grCHG.u_tasks_past_due;


          newRec.u_implementation_variance = grCHG.u_implementation_variance;


          newRec.u_actual_lead_time = grCHG.u_actual_lead_time;


          newRec.u_ci_autofill = grCHG.u_ci_autofill; // Added by Ajay


          newRec.u_business_approver   = grCHG. u_business_approver;


          newRec.u_gis_approval_group = grCHG.u_gis_approval_group;


          // newRec.u_cts_numbers = grCHG.u_cts_numbers;


          newRec.u_src_request = grCHG.u_src_request;


          newRec.u_building_lkp = grCHG.u_building_lkp;


          newRec.u_contact_number = grCHG.u_contact_number;


          newRec.u_cube_location = grCHG.u_cube_location;


          newRec.u_unintended_impact = grCHG.u_unintended_impact;


          newRec.u_failed_change_cause = grCHG.u_failed_change_cause;


          newRec.u_describe_the_impact = grCHG.u_describe_the_impact;


          newRec.u_reason_for_issue = grCHG.u_reason_for_issue;


          newRec.u_remediation_follow_up_action = grCHG.u_remediation_follow_up_action;


          newRec.work_notes = "Change Request created via copy of " + grCHG.number;


         


         


          var new_sys_id = newRec.insert();


          //Copy attachments for this change


          if (do_attachments == true || do_attachments == 'true') {


                if (typeof GlideSysAttachment != 'undefined') {


                      GlideSysAttachment.copy('change_request', grCHG.sys_id, 'change_request', new_sys_id);


                }


                else {


                      GlideSysAttachment.copy('change_request', grCHG.sys_id, 'change_request', new_sys_id);


                }


          }


          gs.addInfoMessage("Change request " + newRec.number + " created");


         


          return new_sys_id;



    },


    type: 'CopyChgAJAX'


});