Name

sn_grc.UserHierarchyUtilsBase

Description

No description available

Script

var UserHierarchyUtilsBase = Class.create();
UserHierarchyUtilsBase.prototype = {
  initialize: function() {
  },

  // Use this method to create user hierarchy config state records for configs if it does not exist
  createStatusRecordOnConfigUnload: function(){
  	return this._createStatusRecordOnConfigUnload();
  },

  _createStatusRecordOnConfigUnload: function(){
  	var userHierarchyConfig = new GlideRecord("sn_grc_user_hierarchy_configuration");
  	userHierarchyConfig.query();
  	while(userHierarchyConfig.next()){
  		this.getUserHierarchyStatusRecord(userHierarchyConfig.getUniqueValue());
  	}
  },

  // Use this method to get user hierarchy config state record if it exists
  getUserHierarchyStatusRecordIfExists: function(configId){
  	return this._getUserHierarchyStatusRecordIfExists(configId);
  },

  _getUserHierarchyStatusRecordIfExists: function(configId){
  	var config_status = new GlideRecord("sn_grc_user_hierarchy_configuration_status");
  	config_status.addQuery("user_hierarchy_configuration",configId);
  	config_status.setLimit(1);
  	config_status.query();
  	if(config_status.next()){
  		return config_status;
  	}
  	return;
  },

  // Use this method to get user hierarchy config state or create status record if doesnt exist
  getUserHierarchyStatusRecord: function(configId){
  	return this._getUserHierarchyStatusRecord(configId);
  },

  _getUserHierarchyStatusRecord: function(configId){
  	var config_status = new GlideRecord("sn_grc_user_hierarchy_configuration_status");
  	config_status.addQuery("user_hierarchy_configuration",configId);
  	config_status.setLimit(1);
  	config_status.query();
  	if(!config_status.next()){
  		config_status.newRecord();
  		config_status.setValue("user_hierarchy_configuration", configId);
  		config_status.insert();
  		return config_status;
  	}
  	return config_status;
  },

  // Use this method to update user hierarchy config state or create status record if doesnt exist
  changeUserHierarchyConfigStatusOrCreateRecord: function(configId, status){
  	return this._changeUserHierarchyConfigStatusOrCreateRecord(configId, status);
  },

  _changeUserHierarchyConfigStatusOrCreateRecord: function(configId, status){
  	var configRecord = this.getUserHierarchyStatusRecord(configId);
  	configRecord.setValue("status", status);
  	configRecord.update();
  },

  // Use this method to trigger user hierarchy events in given app scope
  triggerEventsForUserHierarchyProcessingInScope: function(scope){
  	return this._triggerEventsForUserHierarchyProcessingInScope(scope);
  },

  _triggerEventsForUserHierarchyProcessingInScope: function(scope){
  	if(this.userHierarchyAccessControlEnabled() == "true"){
  		var events = [];
  		var userHierarchyConfig = new GlideRecord("sn_grc_user_hierarchy_configuration");
  		userHierarchyConfig.addEncodedQuery("tableSTARTSWITH"+scope+"_");
  		userHierarchyConfig.addActiveQuery();
  		userHierarchyConfig.query();
  		while(userHierarchyConfig.next()){
  			var tableName = userHierarchyConfig.getValue("table");
  			if(this.checkTableBelongsToScope(tableName, scope)){
  				var eventName = userHierarchyConfig.triggered_event.event_name + "";
  				var eventQueue = userHierarchyConfig.triggered_event.queue;
  				events.push({
  					"eventName": eventName,
  					"queue": eventQueue,
  					"parm1": tableName
  				});
  			}
  		}
  		return events;
  	} else {
  		return [];
  	}
  },

  checkTableBelongsToScope: function(table, scope){
  	return this._checkTableBelongsToScope(table, scope);
  },

  _checkTableBelongsToScope: function(table, scope){
  	var dictionary = new GlideRecord("sys_dictionary");
  	dictionary.addEncodedQuery("internal_type=collection^name="+table);
  	dictionary.setLimit(1);
  	dictionary.query();
  	if(dictionary.next()){
  		if(dictionary.sys_scope.scope + "" == scope){
  			return true;
  		} else {
  			return false;
  		}
  	} else {
  		return false;
  	}
  },

  // Check if user hierarchy access is enabled
  userHierarchyAccessControlEnabled: function(){
  	return this._userHierarchyAccessControlEnabled();
  },

  _userHierarchyAccessControlEnabled: function(){
  	return gs.getProperty("sn_grc.enable_user_hierarchy_access_control", "false");
  },

  // Check if user hierarchy access is enabled for table
  userHierarchyAccessControlEnabledForTable: function(table){
  	return this._userHierarchyAccessControlEnabledForTable(table);
  },

  _userHierarchyAccessControlEnabledForTable: function(table){
  	if(this.userHierarchyAccessControlEnabled() == "true"){
  		var userHierarchyConfig = new GlideRecord("sn_grc_user_hierarchy_configuration");
  		userHierarchyConfig.addQuery("table",table);
  		userHierarchyConfig.addActiveQuery();
  		userHierarchyConfig.setLimit(1);
  		userHierarchyConfig.query();
  		if(userHierarchyConfig.hasNext()){
  			return true;
  		} else {
  			return false;
  		}
  	} else {
  		return false;
  	}
  },


  // Use this method in business rule condition on insert/update for the tables configured to support user hierarchy access control to check if user hierarchy status has to be changed to awaiting processing
  recordHierarchyStatusHasToBeChanged: function(glideRecord){
  	return this._recordHierarchyStatusHasToBeChanged(glideRecord);
  },


  _recordHierarchyStatusHasToBeChanged: function(glideRecord){
  	if(this.userHierarchyAccessControlEnabled() == "false"){
  		return false;
  	}
  	var fieldArray = this.getUserHierarchyFieldsForTable(glideRecord.getTableName());
  	if(fieldArray[0]){
  		var user_field_1 = fieldArray[2];
  		var user_field_2 = fieldArray[3];
  		if(!user_field_1){
  			return false;
  		} else if (glideRecord.getElement(user_field_1).changes()){
  			return true;
  		} else if (!user_field_2){
  			return false;
  		} else if(glideRecord.getElement(user_field_2).changes()){
  			return true;
  		} else {
  			return false;
  		}
  	} else {
  		return false;
  	}
  },

  // Use this method to get the field names for which user hierarchy access has to be supported
  getUserHierarchyFieldsForTable: function(table){
  	return this._getUserHierarchyFieldsForTable(table);
  },

  _getUserHierarchyFieldsForTable: function(table){
  	var userConfiguration = new GlideRecord("sn_grc_user_hierarchy_configuration");
  	userConfiguration.addQuery("table",table);
  	userConfiguration.addActiveQuery();
  	userConfiguration.setLimit(1);
  	userConfiguration.query();
  	if(userConfiguration.next()){
  		var user_field_1 = userConfiguration.getValue("user_reference_field_1");
  		var user_field_2 = userConfiguration.getValue("user_reference_field_2");
  		var user_hierarchy_field_1 = userConfiguration.getValue("user_hierarchy_field_1");
  		var user_hierarchy_field_2 = userConfiguration.getValue("user_hierarchy_field_2");
  		var user_hierarchy_status_field = userConfiguration.getValue("user_hierarchy_status_field");
  		var configStatusRecord = this.getUserHierarchyStatusRecord(userConfiguration.getUniqueValue());
  		return [true,userConfiguration,user_field_1,user_field_2,user_hierarchy_field_1,user_hierarchy_field_2,user_hierarchy_status_field, configStatusRecord];
  	} else {
  		return [false];
  	}
  },

  // Use this method to change user hierarchy status of multiple records to awaiting processing
  changeMultipleRecordsUserHierarchyStatusToAwaitingProcessing: function(table, status_field){
  	return this._changeMultipleRecordsUserHierarchyStatusToAwaitingProcessing(table, status_field);
  },

  _changeMultipleRecordsUserHierarchyStatusToAwaitingProcessing: function(table, status_field){
  	if(gs.nil(status_field)){
  		status_field = "user_hierarchy_status";
  	}
  	var tableRecord = new GlideRecord(table);
  	tableRecord.setValue(status_field,"2");
  	tableRecord.updateMultiple();
  },


  // Use this method to change user hierarchy status of record to awaiting processing
  changeRecordUserHierarchyStatusToAwaitingProcessing: function(glideRecord, status_field){
  	return this._changeRecordUserHierarchyStatusToAwaitingProcessing(glideRecord, status_field);
  },

  _changeRecordUserHierarchyStatusToAwaitingProcessing: function(glideRecord, status_field){
  	var fieldArray = this.getUserHierarchyFieldsForTable(glideRecord.getTableName());
  	if(fieldArray[0]) {
  		var statusField = fieldArray[6];
  		glideRecord[statusField] = "2";
  	}
  },

  // Use this method to calculate and update user hierarchy fields for a gliderecord given the fields
  calculateUserHierarchyForRecord: function(glideRecord, field1, user_hierarchy_field_1, field2, user_hierarchy_field_2,user_hierarchy_status_field){
  	return this._calculateUserHierarchyForRecord(glideRecord, field1, user_hierarchy_field_1, field2, user_hierarchy_field_2,user_hierarchy_status_field);
  },

  _calculateUserHierarchyForRecord: function(glideRecord, field1, user_hierarchy_field_1, field2, user_hierarchy_field_2,user_hierarchy_status_field){
  	if(field1){
  		this.calculateUserHierarchyForField(glideRecord, field1, user_hierarchy_field_1);
  	}
  	if(field2){
  		this.calculateUserHierarchyForField(glideRecord, field2, user_hierarchy_field_2);
  	}
  	glideRecord.setValue(user_hierarchy_status_field,"1");
  	glideRecord.update();
  },

  // Use this method to calculate and update a given user hierarchy field for a gliderecord for the specific field
  calculateUserHierarchyForField: function(glideRecord, userField, userHierarchyField){
  	return this._calculateUserHierarchyForField(glideRecord, userField, userHierarchyField);
  },

  _calculateUserHierarchyForField: function(glideRecord, userField, userHierarchyField){
  	var userFieldValue = glideRecord.getValue(userField);
  	var userHierarchy;
  	if(glideRecord.getElement(userField).nil()){
  		glideRecord.setValue(userHierarchyField, '');
  	} else if(glideRecord.getElement(userHierarchyField).nil() || glideRecord[userHierarchyField]['user'] + "" != userFieldValue){
  		userHierarchy = this.getUserHierarchyRecordForUser(userFieldValue);
  		if(userHierarchy){
  			glideRecord.setValue(userHierarchyField, userHierarchy);
  		} else {
  			var hierarchy = [userFieldValue];
  			this.calculateUserHierarchy(hierarchy, userFieldValue);
  			var recordId = this.createUserHierarchyRecord(userFieldValue, hierarchy.join(","));
  			glideRecord.setValue(userHierarchyField, recordId);
  		}
  	} 
  },

  // Create a record in user hierarchy table for a particular userId and user hierarchy string value
  createUserHierarchyRecord: function(user, userHierarchy){
  	return this._createUserHierarchyRecord(user, userHierarchy);
  },

  _createUserHierarchyRecord: function(user, userHierarchy){
  	var hierarchy = new GlideRecord("sn_grc_user_hierarchy");
  	hierarchy.setValue("user",user);
  	hierarchy.setValue("hierarchy",userHierarchy);
  	hierarchy.setValue("last_synched_on",new GlideDateTime());
  	var recordId = hierarchy.insert();
  	return recordId;
  },


  // Get user hierarchy record for userId
  getUserHierarchyRecordForUser: function(userId){
  	return this._getUserHierarchyRecordForUser(userId);
  },

  _getUserHierarchyRecordForUser: function(userId){
  	var userHierarchy = new GlideRecord("sn_grc_user_hierarchy");
  	userHierarchy.addQuery("user",userId);
  	userHierarchy.setLimit(1);
  	userHierarchy.query();
  	if(userHierarchy.next()){
  		return userHierarchy.getUniqueValue();
  	} else {
  		return "";
  	}
  },

  // Use this method to update the records of a table with user hierarchy reference values in the fields
  processRecordsForUserHierarchy: function(table){
  	return this._processRecordsForUserHierarchy(table);
  },

  _processRecordsForUserHierarchy: function(table){
  	var fieldsArray = this.getUserHierarchyFieldsForTable(table);
  	if(fieldsArray[0] && fieldsArray[7]['status'] == "1"){
  		fieldsArray[7].setValue("source_table_processing_in_progress",true);
  		fieldsArray[7].update();
  		var user_hierarchy_field_1 = fieldsArray[4];
  		if(gs.nil(user_hierarchy_field_1)){
  			user_hierarchy_field_1 = "user_hierarchy_1";
  		}
  		var user_hierarchy_field_2 = fieldsArray[5];
  		if(gs.nil(user_hierarchy_field_2)){
  			user_hierarchy_field_2 = "user_hierarchy_2";
  		}
  		
  		var batchSize = gs.getProperty('sn_grc.batch_size_to_sync_user_hierarchy', '1000');
  		var sourceRecord = new GlideRecord(table);
  		sourceRecord.addQuery(fieldsArray[6],"2");
  		sourceRecord.setLimit(batchSize);
  		sourceRecord.query();
  		while (sourceRecord.next()) {
  			this.calculateUserHierarchyForRecord(sourceRecord, fieldsArray[2], user_hierarchy_field_1, fieldsArray[3], user_hierarchy_field_2,fieldsArray[6]);
  		}
  		if (sourceRecord.getRowCount() == batchSize) {
  			// trigger new event since we got use hierarchy count equal to batch size. There might be more user hieararchy records satisfying the condition.
  			return true;
  		} else {
  			fieldsArray[7].setValue("source_table_processing_in_progress",false);
  			fieldsArray[7].update();
  			return false;
  		}
  	} else {
  		return false;
  	}
  },

  // Use this method to update the record of a table with user hierarchy reference values in the fields
  processRecordForUserHierarchy: function(record){
  	return this._processRecordForUserHierarchy(record);
  },

  _processRecordForUserHierarchy: function(record){
  	var fieldsArray = this.getUserHierarchyFieldsForTable(record.getTableName());

  	if(fieldsArray[0] && fieldsArray[7]['status'] == "1"){
  		fieldsArray[7].setValue("source_table_processing_in_progress",true);
  		fieldsArray[7].update();

  		var user_hierarchy_field_1 = fieldsArray[4];
  		if(gs.nil(user_hierarchy_field_1)){
  			user_hierarchy_field_1 = "user_hierarchy_1";
  		}
  		var user_hierarchy_field_2 = fieldsArray[5];
  		if(gs.nil(user_hierarchy_field_2)){
  			user_hierarchy_field_2 = "user_hierarchy_2";
  		}

  		this.calculateUserHierarchyForRecord(record, fieldsArray[2], user_hierarchy_field_1, fieldsArray[3], user_hierarchy_field_2,fieldsArray[6]);
  		fieldsArray[7].setValue("source_table_processing_in_progress",false);
  		fieldsArray[7].update();
  	} else {
  		return;
  	}
  },

  // Use this to trigger synching user hierarchy values for all user hierarchy records
  triggerUserHierarchySync : function(){
  	return this._triggerUserHierarchySync();
  },

  _triggerUserHierarchySync: function(){
  	gs.eventQueue('sn_grc.sync_user_hierarchies', null, null, null, "sn_grc_user_hierarchy");
  },

  // Use this method to sync hierarchy value for a user hierarchy record
  syncUserHierarchy: function(userHierarchyRecord){
  	return this._syncUserHierarchy(userHierarchyRecord);
  },

  _syncUserHierarchy: function(userHierarchyRecord){
  	if(!userHierarchyRecord || userHierarchyRecord.user.nil()){
  		return;
  	}
  	var hierarchy = [userHierarchyRecord.getValue("user")];
  	this.calculateUserHierarchy(hierarchy, userHierarchyRecord.getValue("user"));
  	userHierarchyRecord.setValue("hierarchy", hierarchy.join(","));
  	userHierarchyRecord.last_synched_on = new GlideDateTime();
  	userHierarchyRecord.update();
  },


  // Calculate hierarchy value for a user record
  calculateUserHierarchy: function(hierarchy, userId){
  	return this._calculateUserHierarchy(hierarchy, userId);
  },

  _calculateUserHierarchy: function(hierarchy, userId){
  	var user = new GlideRecord("sys_user");
  	if(user.get(userId)){
  		var manager = user.getValue("manager");
  		if(manager && hierarchy.indexOf(manager) == -1){
  			hierarchy.push(manager);
  			this._calculateUserHierarchy(hierarchy, manager);
  			return;
  		} else {
  			return;
  		}
  	} 
  	return;
  },

  type: 'UserHierarchyUtilsBase'
};

Sys ID

5e73947977848110e723b23dbd5a9953

Offical Documentation

Official Docs: