
SimpleCopyUtil: A Powerful Record Copying Utility for ServiceNow
Warning, this article has little to do with AI in ServiceNow, but is used to test out Google AI Studio and NotebookLM ability to create articles containing code.
When working with ServiceNow, developers often need to copy or clone records, either within the same table or across different tables. The SimpleCopyUtil
class provides a clean, reusable solution for this common requirement. This utility helps streamline record copying while offering flexibility in field filtering and value setting.
This script will be used as the backbone of the AI copy agent.
Class Documentation
Let’s break down the SimpleCopyUtil
class with detailed JSDoc documentation:
/**
* A utility class for copying records in ServiceNow
* @class SimpleCopyUtil
* @param {GlideRecord} sourceRecord - The source record to copy from
* @param {GlideRecord} [targetRecord=null] - The target record to copy to (optional)
* @param {Array} [filterFields=[]] - Array of fields to exclude from copying
* @param {Object} [setFields={}] - Object containing field names and values to set
*/
var SimpleCopyUtil = Class.create();
SimpleCopyUtil.prototype = {
initialize: function(sourceRecord, targetRecord, filterFields, setFields) {
this.sourceRecord = sourceRecord;
this.targetRecord = targetRecord || null;
this.filterFields = Array.isArray(filterFields) ? filterFields : [];
this.setFields = typeof setFields === 'object' ? setFields : {};
},
/**
* Copies the source record to a new record in the same table
* @method copyRecord
* @returns {String} The sys_id of the newly created record
*/
copyRecord: function() {
this.targetRecord = new GlideRecord(this.sourceRecord.getTableName());
this.targetRecord.initialize();
this._copyFields();
var newSysId = this.targetRecord.insert();
if (!newSysId) {
gs.error("Failed to insert record in copyRecord method.");
return null;
}
return newSysId;
},
/**
* Copies the source record to a new record in a different table
* @method copyRecordNewTable
* @param {String} table - The target table name
* @returns {String} The sys_id of the newly created record
*/
copyRecordNewTable: function(table) {
this.targetRecord = new GlideRecord(table);
this.targetRecord.initialize();
this._copyFields();
var newSysId = this.targetRecord.insert();
if (!newSysId) {
gs.error("Failed to insert record in copyRecordNewTable method.");
return null;
}
return newSysId;
},
/**
* Copies the source record to a new record in a different table without triggering business rules
* @method copyRecordNewTableNoRules
* @param {String} table - The target table name
* @returns {String} The sys_id of the newly created record
*/
copyRecordNewTableNoRules: function(table) {
this.targetRecord = new GlideRecord(table);
this.targetRecord.initialize();
this._copyFields();
this.targetRecord.setWorkflow(false);
this.targetRecord.autoSysField(false);
var newSysId = this.targetRecord.insert();
if (!newSysId) {
gs.error("Failed to insert record in copyRecordNewTableNoRules method.");
return null;
}
return newSysId;
},
_copyFields: function() {
var recordElement;
var recordFields = this.sourceRecord.getFields();
for (var i = 0; i < recordFields.size(); i++) {
recordElement = recordFields.get(i);
var recordElementName = recordElement.getName();
if (recordElementName !== 'sys_id' && recordElementName !== 'number' && !this.filterFields.includes(recordElementName)) {
this.targetRecord.setValue(recordElementName, this.sourceRecord.getValue(recordElementName));
}
}
// Set specific fields using the object structure
for (var field in this.setFields) {
if (this.setFields.hasOwnProperty(field)) {
var fieldValue = this.setFields[field];
this.targetRecord.setValue(field, fieldValue);
}
}
},
/**
* Updates an existing target record with values from the source record
* @method updateRecord
* @returns {void}
*/
updateRecord: function() {
if (this.targetRecord && this.targetRecord.isValidRecord()) {
this._copyFields();
this.targetRecord.update();
} else {
gs.error("Invalid target record for update in updateRecord method.");
}
},
type: 'SimpleCopyUtil'
};
Key Features
- Flexible Field Filtering: Exclude specific fields from being copied
- Custom Field Values: Set specific values for fields in the target record
- Cross-Table Copying: Copy records between different tables
- Business Rule Control: Option to copy without triggering business rules
- Automated Field Mapping: Automatically maps fields between source and target
Best Practices
- Always validate the source record exists before copying
- Use field filtering for sensitive or unique fields
- Consider business rules impact when copying between tables
- Test thoroughly when copying between different table structures
- Use error handling when implementing in production
Implementation Notes
- The utility automatically excludes sys_id and number fields
- Field filtering uses a simple string comparison
- Business rules can be bypassed using copyRecordNewTableNoRules
Examples
Usage Examples
Here are several practical examples of how to use the SimpleCopyUtil:
- Basic Record Copy (Same Table)
var incident = new GlideRecord("incident");
if(incident.get("71c6eb7097a75510c8b7f5b3f153af68")){ // Source incident
var util = new SimpleCopyUtil(incident);
var newSysId = util.copyRecord();
}
- Copy with Fields not being copied
var skipFields = ["caller_id","description"]; // Exclude 'caller_id' and 'description' from copying
var incident = new GlideRecord("incident");
if(incident.get("71c6eb7097a75510c8b7f5b3f153af68")){ // Source incident
var util = new SimpleCopyUtil(incident, null, skipFields);
var newSysId = util.copyRecord();
}
- Copy to Different Table
var skipFields = ["state"]; // Exclude 'state' from copying
var incident = new GlideRecord("incident");
if(incident.get("71c6eb7097a75510c8b7f5b3f153af68")){ // Source incident
var util = new SimpleCopyUtil(incident,null, skipFields);
var newSysId = util.copyRecordNewTable("problem");
}
- Copy with Custom Field Values
var skipFields = ["state", "problem_state", "active"]; // Exclude 'state','problem_state' and 'active' from copying
var setFields = {"cmdb_ci": "affd3c8437201000deeabfc8bcbe5dc3"}; //Set 'cmdb_ci' to a specific value
var problem1 = new GlideRecord("problem");
if (problem1.get("c7140a943b90a610c494291c95e45ab0")) {
var problem2 = new GlideRecord("problem");
if (problem2.get("6e0beede3bd06610c494291c95e45a98")) {
var util = new SimpleCopyUtil(problem1, problem2, skipFields, setFields);
var newSysId = util.updateRecord();
}
}