diff --git a/Server-Side Components/Script Includes/Dynamic Record Archiving/README.md b/Server-Side Components/Script Includes/Dynamic Record Archiving/README.md new file mode 100644 index 0000000000..0cc68b3ddd --- /dev/null +++ b/Server-Side Components/Script Includes/Dynamic Record Archiving/README.md @@ -0,0 +1,32 @@ +# Dynamic Record Archiving Logic + +## Overview +This snippet provides a reusable logic to archive or flag records in ServiceNow that are older than a specified threshold. It helps maintain data hygiene, improve performance, and support compliance with data retention policies. + +You can choose between two modes: +- **Flag Mode**: Marks records as archived using a custom field (`u_archived`). +- **Move Mode**: Moves records to a corresponding archive table (e.g., `incident_archive`) and deletes the original. + +--- + +## Use Case +- Archive incidents older than 1 year. +- Clean up old tasks, requests, or custom records. +- Automate data lifecycle management via Scheduled Jobs. + +--- + +## Parameters +| Parameter | Description | +|---------------------|-----------------------------------------------------------------------------| +| `tableName` | Name of the table to archive (e.g., `incident`) | +| `dateField` | Date field to filter by (e.g., `opened_at`, `created_on`) | +| `archiveThresholdDays` | Number of days before today to consider for archiving (e.g., `365`) | +| `archiveMode` | `'flag'` to mark records, `'move'` to transfer to archive table | + +--- + +## Example Usage +```javascript +var archiver = new RecordArchiver('incident', 'opened_at', 365, 'flag'); +archiver.archiveRecords(); diff --git a/Server-Side Components/Script Includes/Dynamic Record Archiving/code.js b/Server-Side Components/Script Includes/Dynamic Record Archiving/code.js new file mode 100644 index 0000000000..b970fa20eb --- /dev/null +++ b/Server-Side Components/Script Includes/Dynamic Record Archiving/code.js @@ -0,0 +1,53 @@ +var RecordArchiver = Class.create(); +RecordArchiver.prototype = { + initialize: function(tableName, dateField, archiveThresholdDays, archiveMode) { + this.tableName = tableName; + this.dateField = dateField; + this.archiveThresholdDays = archiveThresholdDays; + this.archiveMode = archiveMode || 'flag'; // 'flag' or 'move' + }, + + archiveRecords: function() { + var thresholdDate = new GlideDateTime(); + thresholdDate.addDaysUTC(-this.archiveThresholdDays); + + var gr = new GlideRecord(this.tableName); + gr.addQuery(this.dateField, '<=', thresholdDate); + gr.query(); + + var count = 0; + while (gr.next()) { + if (this.archiveMode === 'flag') { + gr.setValue('u_archived', true); // Assumes a custom field 'u_archived' + gr.update(); + } else if (this.archiveMode === 'move') { + this._moveToArchiveTable(gr); + } + count++; + } + + gs.info('Archived ' + count + ' records from ' + this.tableName); + }, + + _moveToArchiveTable: function(record) { + var archiveGr = new GlideRecord(this.tableName + '_archive'); + archiveGr.initialize(); + + var fields = record.getFields(); + for (var i = 0; i < fields.size(); i++) { + var fieldName = fields.get(i).getName(); + if (archiveGr.isValidField(fieldName)) { + archiveGr.setValue(fieldName, record.getValue(fieldName)); + } + } + + archiveGr.insert(); + record.deleteRecord(); + }, + + type: 'RecordArchiver' +}; + +// Example usage: +//var archiver = new RecordArchiver('incident', 'opened_at', 365, 'flag'); // Archive incidents older than 1 year +//archiver.archiveRecords();