Name
sn_cmdb_ws.CMDBWorkspaceUtil
Description
No description available
Script
var CMDBWorkspaceUtil = Class.create();
CMDBWorkspaceUtil.prototype = Object.extendsObject(CMDBWsConstants, {
initialize: function() {
this.log = new global.GSLog("com.snc.sn_cmdb_ws.log.level", this.type);
},
/**
* Helper function that prepends reference field alias to all fields specified in a query
*
* @param {String} query query supplied by a condition builder
* @param {String} tableAlias tableAlias that's prepended to each field in a query
*
* @example
* this.appendTableName("operational_status=1^nameSTARTSWITHPS", "ci_item")
* // returns ci_item.operational_status=1^ci_item.nameSTARTSWITHPS
*
* @return {String} Returns a query with field names that are prepended with tableAlias specified
*/
appendRefAlias: function(query, tableAlias) {
if (!query)
return "";
//first replace any ^OR or ^NQ at the end of the string with ##OR or ##NQ
query = query.replace(/\^OR$/g, "##OR");
query = query.replace(/\^NQ$/g, "##NQ");
query = query.replace(/\^EQ$/g, "##EQ");
//first replace ^ORs with ##OR - intentionally padding them with ##
query = query.replace(/\^OR/g, "##OR" + tableAlias + ".");
//next replace ^NQs
query = query.replace(/\^NQ/g, "##NQ" + tableAlias + ".");
//next replace ^EQs
query = query.replace(/\^EQ/g, "##EQ" + tableAlias + ".");
//next replace just ^s with the tableAlias dot
query = query.replace(/\^/g, "^" + tableAlias + ".");
//lastly replace ##ORs with ^OR and replace ##NQs with ^NQ
query = query.replace(/##OR/g, '^OR');
query = query.replace(/##NQ/g, '^NQ');
query = query.replace(/##EQ/g, '^EQ');
var encodedQuery = gs.nil(query) ? "" : tableAlias + "." + query;
return encodedQuery;
},
/*
* Iterates thru all the encoded queries within each CMDB Group
* and gets counts for each which are written to sn_cmdb_ws_group_query_metadata.
* Also adds up all the count for the group as a whole.
* Note: the group count is only for encoded queries
* and doesn't include manually selected or QueryBuilder queries.
* The counts are the number of matching CIs for the encoded queries and the group as a whole.
*/
populateNoOfMatchingCIsForEncQrys: function() {
var logMsgs = false;
var gr = new GlideRecord(this.TABLES.CMDB_GROUP);
gr.addQuery(this.COLS.GROUP_TYPE, this.WORKSPACE_PARAM);
gr.query();
if (logMsgs) {
this.log.info('Total Group Count: ' + gr.getRowCount());
}
while (gr.next()) {
if (logMsgs) {
this.log.info('Current group name: ' + gr.group_name);
}
var countForGroup = 0;
countForGroup += this.getNoOfMatchingCIsOnEncQrys(gr.sys_id);
this.insUpdCntGrpMetadata(gr.sys_id, countForGroup);
}
//remove orphaned group metadata records not picked up by cascade delete
this.remOrphanedGrpRecords();
//remove orphaned group query metadata records not picked up by cascade delete
this.remOrphanedGrpQryRecords();
},
/**
* Helper function that counts the number of matching CIs on Encoded Queries and
* inserts/update count into the sn_cmdb_ws_group_query_metadata table
* @param {String} groupSysId
*
* @return {Number} Returns the count of Matching CIs on encoded queries for a group
*/
getNoOfMatchingCIsOnEncQrys: function(groupSysId) {
var tableDisplayNames = {};
var shouldUseSimpleCondition = this.isSimpleConditionEnabled();
var gr = new GlideRecord(this.TABLES.CMDB_GROUP_CONTAINS_ENCODED_QUERY);
gr.addQuery(this.COLS.GROUP, groupSysId);
gr.query();
var countForGroup = 0;
while (gr.next()) {
var className = gr.getValue(this.COLS.CLASS);
var condition = gr.getValue(this.COLS.CONDITION);
if (shouldUseSimpleCondition) {
condition = gr.getValue(this.COLS.SIMPLE_CONDITION);
}
if (gs.tableExists(className)) {
var ga = new GlideAggregate(className);
var numCIs = 0;
ga.addAggregate(this.COUNT_AGGREGATE);
if (condition)
ga.addEncodedQuery(condition);
ga.query();
if (ga.next())
numCIs = parseInt(ga.getAggregate(this.COUNT_AGGREGATE));
countForGroup += numCIs;
if (!tableDisplayNames[className]) {
tableDisplayNames[className] = new GlideRecord(className).getClassDisplayValue();
}
this.insUpdCntGrpQryMetadata(gr.sys_id, numCIs, tableDisplayNames[className]);
}
}
return countForGroup;
},
isSimpleConditionEnabled: function() {
return this.getSystemProperty(this.SYS_PROPERTIES_NAME.SHOULD_USE_SIMPLE_CONDITION, this.DATATYPE.BOOLEAN);
},
/**
* Helper function to update/insert count of CIs in sn_cmdb_ws_group_query_metadata table
* @params {String} sysId
* @params {Number} countCIs
* @params {String} tableDisplayName
*/
insUpdCntGrpQryMetadata: function(sysId, countCIs, tableDisplayName) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_GROUP_QUERY_METADATA);
var foundQuery = gr.get(this.COLS.ENCODED_QUERY, sysId);
if (foundQuery) {
gr.setValue(this.COLS.CI_COUNT, countCIs);
gr.setValue(this.COLS.NAME, tableDisplayName);
gr.update();
} else {
gr.initialize();
gr.setValue(this.COLS.ENCODED_QUERY, sysId);
gr.setValue(this.COLS.CI_COUNT, countCIs);
gr.setValue(this.COLS.NAME, tableDisplayName);
gr.insert();
}
},
/**
* Helper function to update/insert count of CIs in sn_cmdb_ws_group_query_metadata table
* @params {String} sysId
* @params {Number} countForGroup
*/
insUpdCntGrpMetadata: function(sysId, countForGroup) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_GROUP_METADATA);
var foundGroup = gr.get(this.COLS.GROUP, sysId);
if (foundGroup) {
gr.setValue(this.COLS.CI_COUNT, countForGroup);
gr.update();
} else {
gr.initialize();
gr.setValue(this.COLS.GROUP, sysId);
gr.setValue(this.COLS.CI_COUNT, countForGroup);
gr.insert();
}
},
/**
* Helper function to removed orphaned records from sn_cmdb_ws_group_metadata table
*
*/
remOrphanedGrpRecords: function() {
var grGrpMeta = new GlideRecord(this.TABLES.SN_CMDB_WS_GROUP_METADATA);
grGrpMeta.query();
while (grGrpMeta.next()) {
var grGrp = new GlideRecord(this.TABLES.CMDB_GROUP);
var hasGroupMatch = grGrp.get(grGrpMeta.group);
if (!hasGroupMatch) {
grGrpMeta.deleteRecord();
}
}
},
/**
* Helper function to removed orphaned records from sn_cmdb_ws_group_metadata table
*
*/
remOrphanedGrpQryRecords: function() {
var grGrpQry = new GlideRecord(this.TABLES.SN_CMDB_WS_GROUP_QUERY_METADATA);
grGrpQry.query();
while (grGrpQry.next()) {
var grEncQry = new GlideRecord(this.TABLES.CMDB_GROUP_CONTAINS_ENCODED_QUERY);
var hasGroupMatch = grEncQry.get(grGrpQry.encoded_query);
if (!hasGroupMatch) {
grGrpQry.deleteRecord();
}
}
},
populateManagementAggregates: function() {
//only aggregating rejected CIs for now
this._populateRejectedCIs();
},
_populateRejectedCIs: function() {
var rejectedCis = this.getRowCount(this.TABLES.CMDB_CI, 'attestation_status=Rejected');
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.RETIRED, this.CATEGORY.REJECTED_CIS);
this.populateBaseAggData(this.CATEGORY.REJECTED_CIS, null, rejectedCis, this.STATES.DRAFT);
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.CATEGORY.REJECTED_CIS);
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.CATEGORY.REJECTED_CIS);
},
/**
* Helper function to check if CIs Managed By Me should be included on landing page
* @return {Boolean}
*/
showCIsManagedByMe: function() {
var propEnabled = this.getSystemProperty(this.SYS_PROPERTIES_NAME.CIS_MANAGED_BY_ME, this.DATATYPE.BOOLEAN);
var hasMinimumRole = this.userHasRole(this.ROLES.SN_CMDB_EDITOR);
return propEnabled && hasMinimumRole;
},
/**
* Helper function to check if Total CIs should be included on landing page
* @return {Boolean}
*/
showTotalCIs: function() {
var propEnabled = this.getSystemProperty(this.SYS_PROPERTIES_NAME.ENABLE_TOTAL_CIS, this.DATATYPE.BOOLEAN, 'true');
return propEnabled;
},
/**
* Helper function to check if Important Actions should be included on the landing page
* @return {Boolean}
*/
showImportantActions: function() {
var isAdminOrMaint = this.isUserAdminOrMaint();
var isCMDBAdmin = this.userHasRole(this.ROLES.SN_CMDB_ADMIN);
var isCMDBEditor = this.userHasRole(this.ROLES.SN_CMDB_EDITOR);
return (isAdminOrMaint || isCMDBAdmin || isCMDBEditor);
},
/**
* Helper function to check if CMDB Health should be included on the landing page
* @return {Boolean}
*/
showCmdbHealth: function() {
var isAdminOrMaint = this.isUserAdminOrMaint();
var hasAssetRole = this.userHasRole(this.ROLES.ASSET);
var isCMDBEditor = this.userHasRole(this.ROLES.SN_CMDB_EDITOR);
var isCMDBUser = this.userHasRole(this.ROLES.SN_CMDB_USER);
return (isAdminOrMaint || isCMDBEditor || (isCMDBUser && hasAssetRole));
},
/**
* Parse a string to a boolean
* @params {String}
* @return {boolean}
*/
parseBooleanString: function(booleanString) {
if (booleanString)
return booleanString === 'true' ? true : false;
return false;
},
/**
* Parse a string to a number
* @params {String}
* @return {Number}
*/
parseNumericString: function(numericString) {
if (numericString) {
var val = Number(numericString);
return isNaN(val) ? null : val;
}
return;
},
/**
* Helper function to check if current user has given role
* @return {Boolean}
*/
userHasRole: function(role) {
return gs.hasRole(role);
},
/**
* Helper function to check if current user is admin or maint
* @return {Boolean}
*/
isUserAdminOrMaint: function() {
return this.userHasRole(this.ROLES.ADMIN) || this.userHasRole(this.ROLES.MAINT);
},
/**
* Helper function to check if the given table has any action config that we have set
* @return {Boolean}
*/
tableHasActionConfig: function(table) {
return this.hasRecord(this.TABLES.M2M_ACTION_ASSIGNMENT_ACTION_CONFIG, null, {
'action_configuration': this.CMDB_WORKSPACE_ACTION_CONFIG_ID,
'action_assignment.table': table
});
},
/**
* Helper function to get if the given table and query result in at least one valid record
* @params {String} table
* @params {String} encodedQuery
* @params {Object} query
* @return {boolean} whether the table has at least one record that satifies the queries
*/
hasRecord: function(table, encodedQuery, query) {
var gr = new GlideRecord(table);
this.addQueryConditions(gr, encodedQuery, query);
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
/**
* Helper function to get the row count on the given table with given queries
* @params {String} table
* @params {String} encodedQuery
* @params {Object} query
* @return {number} row count that satisfies the query condition
*/
getRowCount: function(table, encodedQuery, query) {
var ga = new GlideAggregate(table);
this.addQueryConditions(ga, encodedQuery, query);
ga.addAggregate(this.COUNT_AGGREGATE);
ga.query();
if (ga.next()) {
return ga.getAggregate(this.COUNT_AGGREGATE);
}
return 0;
},
addQueryConditions: function(gr, encodedQuery, query) {
if (encodedQuery) {
gr.addEncodedQuery(encodedQuery);
}
if (query) {
var fields = Object.keys(query);
for (var i = 0; i < fields.length; i++) {
gr.addQuery(fields[i], query[fields[i]]);
}
}
},
/**
* Helper function to check if a plugin is active
* @params {String} pluginId
* @return {boolean} whether the given plugin is active or not
*/
isPluginActive: function(pluginId) {
return new GlidePluginManager().isActive(pluginId);
},
/**
* Helper function to get the value for the given sys_property
* @params {String} key
* @params {DATATYPE} datatype
* @params {any} defaultValue
* @return {Object} value
*/
getSystemProperty: function(key, dataType, defaultValue) {
var val = gs.getProperty(key, defaultValue);
switch (dataType) {
case this.DATATYPE.BOOLEAN:
return this.parseBooleanString(val);
case this.DATATYPE.NUMBER:
return this.parseNumericString(val);
default:
return val;
}
},
/**
* Helper function to check if license is active for given appId
* @params {String} appId
* @return {Object} whether the license is active or not
*/
hasActiveLicense: function(appId) {
return new sn_lef.GlideLicenseAPI().hasLicenseForFeature("app_id", appId);
},
populateBaseAggData: function(chart, groupby, count, state) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.initialize();
gr.setValue(this.COLS.CHART, chart);
if (groupby)
gr.setValue(this.COLS.GROUP_BY, groupby);
gr.setValue(this.COLS.COUNT, count);
gr.setValue(this.COLS.STATE, state);
gr.insert();
},
updateBaseAggDataState: function(sourceState, targetState, chart) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
if (chart)
gr.addQuery(this.COLS.CHART, chart);
gr.addQuery(this.COLS.STATE, sourceState);
gr.setValue(this.COLS.STATE, targetState);
gr.updateMultiple();
},
deleteFeatureCategoryAggregate: function(featureId, state, groupby) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.addQuery(this.COLS.CHART, featureId);
if (global.JSUtil.notNil(state)) {
gr.addQuery(this.COLS.STATE, state);
}
if (global.JSUtil.notNil(groupby)) {
gr.addQuery(this.COLS.GROUP_BY, groupby);
}
gr.query();
while (gr.next()) {
gr.deleteRecord();
}
},
updateDraftFeatureCategoryAggregate: function(featureId, state, count, groupby) {
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.addQuery(this.COLS.CHART, featureId);
gr.addQuery(this.COLS.STATE, this.STATES.DRAFT);
if (global.JSUtil.notNil(groupby)) {
gr.addQuery(this.COLS.GROUP_BY, groupby);
}
gr.query();
while (gr.next()) {
if (global.JSUtil.notNil(state)) {
gr.setValue(this.COLS.STATE, state);
}
if (global.JSUtil.notNil(count)) {
gr.setValue(this.COLS.COUNT, count);
}
gr.update();
}
},
getAggregateData: function(featureId, groupByFilter, stateFilter) {
var result = [];
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.addQuery(this.COLS.CHART, featureId);
if (groupByFilter) {
gr.addQuery(this.COLS.GROUP_BY, groupByFilter);
}
if (stateFilter) {
gr.addQuery(this.COLS.STATE, stateFilter);
}
gr.query();
while (gr.next()) {
result.push({
chart: gr.getValue(this.COLS.CHART),
groupBy: gr.getValue(this.COLS.GROUP_BY),
count: +gr.getValue(this.COLS.COUNT),
updatedDt: gr.getValue(this.COLS.SYS_UPDATED_ON)
});
}
return result;
},
isJson: function(str) {
try {
return JSON.parse(str);
} catch (e) {
return false;
}
},
getRelative24hrEncodedQuery: function(column) {
return column + "RELATIVEGT@hour@ago@24";
},
/**
* Generic method to make outbound REST API call.
* @params {String} url
* @return {Object} response with status and body
*/
httpGet: function(url) {
var response;
try {
var sm = new sn_ws.RESTMessageV2();
sm.setEndpoint(url);
sm.setHttpMethod('get');
response = sm.execute();
var responseBody = response.haveError() ? response.getErrorMessage() : JSON.parse(response.getBody());
response = {
status: response.getStatusCode(),
body: responseBody
};
} catch (ex) {
var errorMessage = ex.getMessage ? ex.getMessage() : "Error fetching data";
response = {
status: 500,
body: errorMessage
};
}
return response;
},
/**
* Gets AppStore url.
* @return {String} appstore url
*/
getAppStoreBaseUrl: function() {
return this.getSystemProperty(this.SYS_PROPERTIES_NAME.APPSTORE_BASE_URL, this.DATATYPE.STRING, "https://store.service-now.com/");
},
/**
* Given relative path for appstore, this returns the absolute url relevant for this instance
*/
buildAppStoreUrl: function(relativePath) {
var baseUrl = this.getAppStoreBaseUrl();
baseUrl = baseUrl.replace(/\/+$/, "");
var relPath = relativePath.replace(/^\/+/, "");
return baseUrl + "/" + relPath;
},
invokePAJob: function(paJobId, jobName) {
var paJobRecord = new GlideRecord(this.TABLES.SYSAUTO_PA);
if (paJobRecord.get(paJobId)) {
var paJobName = paJobRecord.getValue(this.COLS.NAME);
gs.debug("Invoking job : '{0}' to calculate trends for aggregated charts", paJobName);
var paTriggerId = gs.executeNow(paJobRecord);
gs.info("Triggered job : '{0} ' with trigger id : {1} ", paJobName, paTriggerId);
} else {
gs.error("Failed to find PA job with sys Id {0} and cannot execute the {1} job", paJobId, jobName);
}
},
invokeWsAggregatesMonthlyPAJob: function() {
this.invokePAJob(this.SCHEDULED_JOBS.CMDB_WS_AGGREGATES_MONTHLY_PA_JOB, "CMDB Workspace Monthly Collection");
},
invokeWsAggregatesDailyPAJob: function() {
this.invokePAJob(this.SCHEDULED_JOBS.CMDB_WS_AGGREGATES_DAILY_PA_JOB, "CMDB Workspace Aggregates Collection");
},
invokeScriptJob: function(scriptJobId, jobName) {
var scriptJobRecord = new GlideRecord(this.TABLES.SYSAUTO_SCRIPT);
if (scriptJobRecord.get(scriptJobId)) {
var scriptJobName = scriptJobRecord.getValue(this.COLS.NAME);
gs.debug("Invoking job : '{0}'", scriptJobName);
var scriptTriggerId = gs.executeNow(scriptJobRecord);
gs.info("Triggered job : '{0} ' with trigger id : {1} ", scriptJobName, scriptTriggerId);
} else {
gs.error("Failed to find script job with sys_id {0} and cannot execute the {1} job", scriptJobId, jobName);
}
},
invokeWsPopulateAggregatesDailyScriptJob: function() {
this.invokeScriptJob(this.SCHEDULED_JOBS.CMDB_WS_POPULATE_AGGREGATES_DAILY, "CMDB Workspace - Populate aggregates Daily");
},
invokeWsPopulateAggregatesMonthlyScriptJob: function() {
this.invokeScriptJob(this.SCHEDULED_JOBS.CMDB_WS_POPULATE_AGGREGATES_MONTHLY, "CMDB Workspace - Populate aggregates Monthly");
},
/**
* Abbreviates a number
* @params {Number} num
* @return {String} abbreviated number
*/
abbreviateNumber: function(num) {
if (global.JSUtil.nil(num)) return null;
var formatNumStr = function(numberStr, suffix) {
if (numberStr.endsWith('.0')) {
return numberStr.slice(0, -2) + suffix;
}
return numberStr + suffix;
};
if (num < 1e3) {
return num.toString();
}
if (num >= 1e3 && num < 1e6) {
return formatNumStr((num / 1e3).toFixed(1), 'K');
}
if (num >= 1e6 && num < 1e9) {
return formatNumStr((num / 1e6).toFixed(1), 'M');
}
return formatNumStr((num / 1e9).toFixed(1), 'B');
},
getJobLastCompletedInfo: function(jobId) {
var completedDateTime = gs.getMessage("N/A");
var gr = new GlideRecord(this.TABLES.PA_JOB_LOGS);
gr.addQuery(this.COLS.JOB, jobId);
gr.addQuery(this.COLS.STATE, this.PA_JOB_LOGS_STATE.COLLECTED_OK);
gr.setLimit(1);
gr.orderByDesc(this.COLS.SYS_CREATED_ON);
gr.query();
if(gr.next()) {
completedDateTime = gr.getDisplayValue(this.COLS.COMPLETED);
}
return completedDateTime;
},
getCMDBWsPAJobsLastCompletedInfo: function() {
var result = {};
var jobs = {};
jobs[this.SCHEDULED_JOB_RUN_TYPE.AGGREGATES_DAILY_JOB] = this.SCHEDULED_JOBS.CMDB_WS_AGGREGATES_DAILY_PA_JOB;
jobs[this.SCHEDULED_JOB_RUN_TYPE.AGGREGATES_MONTHLY_JOB] = this.SCHEDULED_JOBS.CMDB_WS_AGGREGATES_MONTHLY_PA_JOB;
for (var runType in jobs) {
var dateTime = this.getJobLastCompletedInfo(jobs[runType]);
result[runType] = gs.getMessage("Last updated: {0}", dateTime);
}
return result;
},
getIndicatorDetails: function(indicatorId, breakdownId, breakdownElementId, includeScores, limit) {
var scorecard = new PAScorecard();
var uuid = indicatorId;
if (!global.JSUtil.nil(breakdownId)) {
uuid += ":" + breakdownId;
if (!global.JSUtil.nil(breakdownElementId)) {
uuid += ":" + breakdownElementId;
}
}
if (!global.JSUtil.nil(limit)) {
scorecard.addParam("limit", limit);
}
scorecard.addParam("uuid", uuid);
scorecard.addParam("include_scores", global.JSUtil.nil(includeScores) ? true : includeScores);
scorecard.addParam("display", "all");
return scorecard.query();
},
/**
* Checks if at least one score is greater than given value
*/
atLeastOneScoreGreaterThan: function(scores, gtValue) {
if (global.JSUtil.nil(scores)) {
return false;
}
var val = global.JSUtil.nil(gtValue) ? 0 : gtValue;
for (var idx in scores) {
if (scores[idx].value > val) return true;
}
return false;
},
getSysChoiceId: function(encodedQuery, query) {
var gr = new GlideRecord(this.TABLES.SYS_CHOICE);
this.addQueryConditions(gr, encodedQuery, query);
gr.setLimit(1);
gr.query();
return gr.next() ? gr.getUniqueValue() : '';
},
lookupIndicatorId: function(indicator) {
var id = null;
var gr = new GlideRecord(this.TABLES.PA_INDICATORS);
if (gr.get(indicator)) {
id = gr.getValue(this.COLS.ID);
}
return id;
},
/* Helper function to copy scores from one indicator to another,
* @params {String} sourceIndicator
* @params {String} targetIndicator
* @return null - nothing to be returned, scores from sourceIndicator should be inserted to the pa_scores_l1 table, as scores for targetIndicator
*
*/
migratePaIndicatorScores: function(sourceIndicator, targetIndicator) {
//first, look up 'id' of each indicator, because pa_scores_l1 takes in indicator id, and not the sys_id. Not sure why
var sourceIndicatorId = this.lookupIndicatorId(sourceIndicator);
var targetIndicatorId = this.lookupIndicatorId(targetIndicator);
//grab the earliest date of the pa scores for new indicator
var earliestScoreDate = null;
var gr = new GlideRecord(this.TABLES.PA_SCORES_L1);
gr.addQuery(this.COLS.INDICATOR, targetIndicatorId);
gr.orderBy(this.COLS.START_AT);
gr.setLimit(1);
gr.query();
//get scores before earliest date for old indicator
var earliestDate = null;
if (gr.next()) {
earliestDate = gr.getValue(this.COLS.START_AT);
}
//grab all pa_scores_l1 records for sourceIndicator, before the earliest score date of new indicator
//for each of the scores, create another score entry with the same scores and dates, for the new indicator
gr = new GlideRecord(this.TABLES.PA_SCORES_L1);
gr.addQuery(this.COLS.INDICATOR, sourceIndicatorId);
if (earliestDate) {
gr.addQuery(this.COLS.START_AT, this.OPERATORS.LESSTHAN, earliestDate);
}
gr.query();
while (gr.next()) {
var scoreDate = gr.getValue(this.COLS.START_AT);
var scoreValue = gr.getValue(this.COLS.VALUE);
//create new scores for the new indicator.
var newGr = new GlideRecord(this.TABLES.PA_SCORES_L1);
newGr.initialize();
newGr.setValue(this.COLS.INDICATOR, targetIndicatorId); //new indicator id
newGr.setValue(this.COLS.START_AT, scoreDate);
newGr.setValue(this.COLS.VALUE, scoreValue);
newGr.insert();
}
},
migrateTotalCIsIndicator: function() {
var oldTotalCiIndicator = 'b6dd71e077511110ee0d0cc2fa5a990e';
var newTotalCiIndicator = 'b1fb06f0ef572110785294c1ed97d705';
this.migratePaIndicatorScores(oldTotalCiIndicator, newTotalCiIndicator);
},
type: 'CMDBWorkspaceUtil'
});
Sys ID
114ce4a553a720102365ddeeff7b122a