Name

sn_hr_core.hr_TransferCase

Description

Handles transferring and reclassifying HR Cases

Script

var hr_TransferCase = Class.create();

/*
* Gets the extension points for the transfer methods relevant to a specific HR Case
*
* @param {String} tableName - the COE of the HR Case
* @param {String} sysId - the sys_id of the HR Case
*
* @returns {Array}
*/
hr_TransferCase.getTransferMethods = function(tableName, sysId) {
  var gr = new GlideRecord(tableName);	
  if (!gr.get(sysId))
  	return [];

  var allExtensionPoints = new GlideScriptedExtensionPoint().getExtensions('sn_hr_core.HRCaseTransfer');
  var transferUtil = new hr_TransferCase();
  var defaultTransferMethodId = transferUtil._getDefaultTransferMethodId();

  // Add non-default transfer methods that are eligible to be shown (criteria met)
  var transferMethods = allExtensionPoints.filter(function(epImpl) {
  	var configId = epImpl.getConfigurationId();
  	var gr = new GlideRecord('sn_hr_core_transfer_case_config');

  	if (!gr.get(configId))
  		return false;

  	if (configId == defaultTransferMethodId)
  		return false;

  	if (!transferUtil.isTransferCaseConfigCriteriaSatisfied(gr))
  		return false;

  	if (!epImpl.isCaseEligibleForMethod(gr))
  		return false;

  	return true;
  });

  // Add default transfer method to beginning
  var defaultMethod = allExtensionPoints.filter(function(epImpl) {
  	return epImpl.getConfigurationId() == defaultTransferMethodId;
  });

  if (defaultMethod.length > 0)
  	transferMethods.unshift(defaultMethod[0]);

  return transferMethods;
};


/*
* Gets the display description text for the specified transfer method
*
* @param {Object} epImpl - The specified scripted extension point instance of 'sn_hr_core.HRCaseTransfer' to check
*
* @returns {String} - The display text that will display for this type, or null if no text was specified
*/

hr_TransferCase.getDescription = function(epImpl) {
  var configId = epImpl.getConfigurationId();
  var gr = new GlideRecord('sn_hr_core_transfer_case_config');
  
  if (configId && gr.get(configId))
  	return gr.getDisplayValue('display_text');
  
  return null;
};

/*
* Completes the case transfer, using the specified transfer method and inputs
*
* @param {GlideRecord} originalRecord - the record of the case to be transferred
* @param {string} transferType - the script include name of the chosen extension point instance to use
* @param {Object} inputs - Object with additional input parameters needed for the transfer
*
* @returns {GlideRecord} newly created record
*/

hr_TransferCase.performSelectedTransfer = function(originalRecord, transferType, inputs) {
  var transferMethods = hr_TransferCase.getTransferMethods(originalRecord.getRecordClassName(), originalRecord.getUniqueValue());
  var selectedMethod = transferMethods.filter(function(method) {
  	return method.type == transferType; })[0];

  var newRecord = selectedMethod.transferCase(originalRecord, inputs);
  return newRecord;
};


hr_TransferCase.prototype = {
  initialize: function() {},
  
  /*
   * Determines whether the HR Criteria defined on a HR Transfer Case Configuration record are satisfied. 
   * If true, the logged in agent can perform this transfer on a case.
   *
   * @param {Object} gr - the GlideRecord of the sn_hr_core_transfer_case_config record to check
   *
   * @returns {boolean} - true if no criteria were defined, or at least one in the list returned true
   */
  isTransferCaseConfigCriteriaSatisfied : function(gr) {
  	// Disable access if the configuration is not active
  	if (!gr.active)
  		return false;

  	// No criteria specified should allow all agents access
  	if (gr.hr_criteria.nil())
  		return true;

  	var hrCriteriaUtil = new hr_Criteria();
  	var criteriaIdList = gr.hr_criteria.split(',');
  	var userToEvaluate = gs.getUserID();

  	for (var i = 0; i < criteriaIdList.length; i++) {
  		if (hrCriteriaUtil.evaluateById(criteriaIdList[i], userToEvaluate))
  			return true;
  	}

  	return false;
  },

  /*
   * Copy fields from one record to another
   *
   * @param {GlideRecord} originalRecord - the record of the case to be transferred
   * @param {GlideRecord} newRecord - the record of the case to be transferred to
   *
   * @returns {void}
   */
  _copyFields: function(originalRecord, newRecord) {
  	var fields = originalRecord.getElements();
  	
  	var deprecatedFields = [];
  	var ignoredFields = gs.getProperty('sn_hr_core.transfer_case.ignored_fields', '');
  	// Trim input field names from the property so that they can be searched for in the array
  	var IGNORED_FIELDS = ignoredFields.split(",").map(function(item) {
  		return item.trim();
  	});

  	var INACTIVE_FIELDS = [];
  	
  	var gr = new GlideRecord('sys_dictionary');
  	gr.addQuery('active', false);
  	gr.addQuery('name', 'IN', new GlideTableHierarchy(originalRecord.getRecordClassName()).getTables());
  	gr.query();
  	
  	while (gr.next())
  		INACTIVE_FIELDS.push(gr.getValue('element'));
  	
  	for (var i = 0; i < fields.length; i++) {
  		var field = fields[i];
  		var fieldName = field.getName();

  		if (!fieldName.startsWith("sys_") && INACTIVE_FIELDS.indexOf(fieldName) == -1 && IGNORED_FIELDS.indexOf(fieldName) == -1) {
  			if (newRecord.isValidField(fieldName)) {
  				newRecord[fieldName] = originalRecord[fieldName];
  			} else {
  				var value = field.getDisplayValue();
  				if (value) {
  					var label = field.getLabel();
  					var note = label + " - " + value; 
  					deprecatedFields.push(note);	
  				}
  			}
  		}
  	}
  	
  	if (deprecatedFields.length > 0) {
  		// Add new line for formatting
  		deprecatedFields.unshift("\n");

  		var deprecatedFieldNotes = gs.getMessage("Non-transferrable fields: {0}", deprecatedFields.join("\n"));
  		newRecord.work_notes = deprecatedFieldNotes;
  	}
  },

  /*
   * Copy attachments from one record to another
   *
   * @param {GlideRecord} originalRecord - the record of the case to be transferred
   * @param {GlideRecord} newRecord - the record of the case to be transferred to
   *
   * @returns {void}
   */
  _copyAttachments: function(originalRecord, newRecord) {
  	var attachments = new GlideSysAttachment().copy(
  		originalRecord.getTableName(),
  		originalRecord.getUniqueValue(),
  		newRecord.getRecordClassName(),
  		newRecord.getUniqueValue()
  	);

  	// The code that added a comment when attachments were copied was removed due to an issue with 
  	// displaying the activity stream when multiple comments happen at same millisecond.
  },

  /*
   * Copy work notes from one record to another
   *
   * @param {GlideRecord} originalRecord - the record of the case to be transferred
   * @param {GlideRecord} newRecord - the record of the case to be transferred to
   *
   * @returns {void}
   */
  _copyWorkNotes: function(originalRecord, newRecord) {
  	var originalWorkNotes = originalRecord.work_notes.getJournalEntry(-1);
  	var originalComments = originalRecord.comments.getJournalEntry(-1);
  	newRecord.work_notes = originalWorkNotes;
  	newRecord.comments = originalComments;
  },
  
  _copyOnlyWorkNotes: function(originalRecord, newRecord) {
  	var originalWorkNotes = originalRecord.work_notes.getJournalEntry(-1);
  	newRecord.work_notes = originalWorkNotes;	
  },
  
  _copyCommentsForUR: function(originalRecord, newRecord) {
  	var urUtilsApi = new sn_uni_req.UniversalRequestUtils();
  	urUtilsApi.transferPrimaryTicket(originalRecord.getUniqueValue(), newRecord.getUniqueValue(), null);
  },

  /*
   * Copy interaction related records
   *
   * @param {GlideRecord} originalRecord - the record of the case to be transferred
   * @param {GlideRecord} newRecord - the record of the case to be transferred to
   *
   * @returns {void}
   */
  copyInteractionRelatedRecords: function(originalRecord, newRecord) {
  	var grInteractionRelated = new GlideRecord('interaction_related_record');
  	grInteractionRelated.addQuery('task', originalRecord.getUniqueValue());
  	grInteractionRelated.query();
  	
  	while (grInteractionRelated.next()) {
  		var grInteractionRelatedNew = new GlideRecord('interaction_related_record');
  		grInteractionRelatedNew.initialize(); 
  		grInteractionRelatedNew.setValue('document_id', newRecord.getUniqueValue());
  		grInteractionRelatedNew.setValue('task', newRecord.getUniqueValue());
  		grInteractionRelatedNew.setValue('document_table', newRecord.getTableName());
  		grInteractionRelatedNew.setValue('type', 'task');
  		grInteractionRelatedNew.setValue('interaction', grInteractionRelated.interaction);
  		grInteractionRelatedNew.insert();
  	}
  },
  
  /*
   * Create a new case from the service ID
   *
   * @param {GlideRecord} service - the record of the target service
   *
   * @returns {GlideRecord} the newly created case record
   */
  _createCaseFromService: function(service) {
  	return new GlideRecord(service.topic_detail.topic_category.coe);
  },
  
  /**
   * Due to issues when task.number has a unique index, this method will no longer "swap", but will generate
   * a brand new number for the old case and give the new case the old case's number. AFter the call to this 
   * method, the old case needs to be updatedin the DB prior to the new case being updated.
   * @param {GlideRecord} originalRecord - the record of the case to be transferred
   * @param {GlideRecord} newRecord - the record of the case to be transferred to
  */
  swapNumber: function(originalRecord, newRecord) {
  	var originalRecordNumber = String(originalRecord.number);
  	var newNumberForOldCase = "";
  	
  	var lePluginActive = GlidePluginManager.isActive("com.sn_hr_lifecycle_events");
  	var leUtils = lePluginActive ? new sn_hr_le.hr_LETransferUtils() : '';
  	
  	var erPluginActive = GlidePluginManager.isActive("com.sn_hr_employee_relations");
  	var erUtils = erPluginActive ? new sn_hr_er.er_TransferUtils() : '';
  	var setNumber = function(record, numberToSet) {
  		if (lePluginActive && leUtils.isLECase(record))
  			leUtils.setNumber(record, numberToSet);
  		else if (erPluginActive && erUtils.isERCase(record))
  			erUtils.setNumber(record, numberToSet);
  		else
  			record.number = numberToSet;
  	};

  	newNumberForOldCase = new global.HRSecurityUtils().getNextObjNumberPadded(originalRecord.getRecordClassName());
  	
  	setNumber(originalRecord, newNumberForOldCase);
  	setNumber(newRecord, originalRecordNumber);
  	
  },

  /*
   * Gets the latest accessible HR Case in a sequence of transfers from an original case
   *
   * @param {GlideRecord} gr - The case to start from
   *
   * @returns {GlideRecord} - The latest transfer the user can access
   */
  getLatestTransfer: function(gr) {
  	// Follow the chain of transfers to the latest case if the
  	// visited case has been transferred multiple times
  	var currentCase = gr;
  	var nextCase;
  	while (!currentCase.transferred_to.nil()) {
  		nextCase = currentCase.transferred_to.getRefRecord();
  		
  		if (!nextCase.canRead())
  			break;
  		
  		currentCase = nextCase;
  	}
  	
  	return currentCase;
  },
  
  _getDefaultTransferMethodId : function() {
  	var gr = new GlideRecord('sn_hr_core_transfer_case_config');
  	
  	if (gr.get('is_default', true))
  		return gr.getUniqueValue();
  	
  	return null;
  },
  
  setDefaultTransferMethod: function(configSysId) {
  	
  	//Add default flag to the new config
  	var grNewDefault = new GlideRecord('sn_hr_core_transfer_case_config');
  	grNewDefault.addQuery('is_default', false);
  	grNewDefault.addQuery('sys_id', configSysId);
  	grNewDefault.query();
  	
  	if (grNewDefault.next()) {
  		grNewDefault.setValue('active', true);
  		grNewDefault.setValue('is_default', true);
  		if (grNewDefault.update() == null)
  			return false;
  	}
  	
  	//Remove default flag from a different config
  	var grOldDefault = new GlideRecord('sn_hr_core_transfer_case_config');
  	grOldDefault.addQuery('is_default', true);
  	grOldDefault.addQuery('sys_id', '!=', configSysId);
  	grOldDefault.query();
  	
  	if (grOldDefault.next()) {
  		grOldDefault.setValue('is_default', false);
  		grOldDefault.update();
  	}
  	
  	return true;
  },

  type: 'hr_TransferCase'
};

Sys ID

32678a3453b72300ff25ddeeff7b1213

Offical Documentation

Official Docs: