Name

sn_hr_core.hr_UserCriteriaEvaluation

Description

This script include evaluates the number of users matching the given User Criteria.

Script

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

  /* Determine if a User meets a User Criteria
   *
   * @param userCriteriaId String sys_id of the user_criteria to check
   * @param userId String sys_id of the user to check for
   * @return boolean whether the @param userId meets the @param userCriteriaId
   */
  checkUserMeetsUserCriteria: function(userCriteriaId, userId) {
  	if (!userCriteriaId || !userId)
  		return false;

  	var userMatchGr;
  	var userCriteriaResult = this._getUserCriteriaFilters(userCriteriaId, true, userId);

  	if (userCriteriaResult.isMatchAll) {
  		if (userCriteriaResult.resultQuery != "") {
  			userMatchGr = new GlideRecord("sys_user");
  			userMatchGr.addEncodedQuery(userCriteriaResult.resultQuery);
  			userMatchGr.addQuery("sys_id", userId);
  			userMatchGr.query();
  			if (!userMatchGr.hasNext())
  				return false;
  			if (userCriteriaResult.hasRolesOrGroups)	
  				return userCriteriaResult.generatedMatchAllResult;
  			return true;	
  		}
  	} else {				
  		if (userCriteriaResult.resultQuery != "" || (userCriteriaResult.resultQuery == "" && !userCriteriaResult.hasRolesOrGroups)) {
  			userMatchGr = new GlideRecord("sys_user");
  			userMatchGr.addEncodedQuery(userCriteriaResult.resultQuery);
  			userMatchGr.addQuery("sys_id", userId);
  			userMatchGr.query();
  			if (userMatchGr.hasNext())
  				return true;
  			if (userCriteriaResult.hasRolesOrGroups)
  				return userCriteriaResult.generatedMatchAllResult;
  			return false;
  		}
  	}

  	if (userCriteriaResult.hasRolesOrGroups)
  		return userCriteriaResult.generatedMatchAllResult;

  	return false;
  },

  /* Get object from @function _getUserCriteriaFilters describing users that match a user_criteria
   *
   * @param userCriteriaId String sys_id of a user_criteria record
   * @return Object from @function _getUsersBasedOnQueries, or String encoded query
   */
  getAllUsersForUserCriteria: function(userCriteriaId){
  	if (!userCriteriaId)
  		return "sys_idINEMPTY";

  	return this._getUserCriteriaFilters(userCriteriaId, false, "");
  },

  /* Get Object from @function _getUserCriteriaFilters describing users that match a user_criteria
   *
   * @param userCriteriaId String sys_id of a user_criteria record
   * @param checkForSingleUser boolean Check user_criteria for a specific user
   * @param userId (optional) String sys_id of the user to evaluate
   * @return Object from @function _getUsersBasedOnQueries
   */
  _getUserCriteriaFilters: function(userCriteriaId, checkForSingleUser, userId) {
  	var userCriteriaGr = new GlideRecord('user_criteria');
  	userCriteriaGr.addActiveQuery();
  	userCriteriaGr.addQuery('sys_id', userCriteriaId);
  	userCriteriaGr.addQuery("advanced", false);
  	userCriteriaGr.query();
  	if (userCriteriaGr.next())
  		return this._getUsersBasedOnQueries(userCriteriaGr, checkForSingleUser, userId);
  	
  	// returns empty records when user criteria is not found or it is an advance user criteria.
  	var userCriteriaResult = {
  		isMatchAll: false,
  		generatedMatchAllResult: true,
  		resultQuery: "sys_idISEMPTY",
  		hasRolesOrGroups: false,
  		shouldHideCount: false
  	};
  	
  	return userCriteriaResult; // get the default return object
  },

  /* Create an object to describe users that match a user_criteria
   *
   * @param criteriaGr GlideRecord of a User Criteria
   * @param checkForSingleUser boolean Check user_criteria for a specific user
   * @param userId String (optional) sys_id of the user to evaluate
   * @return Object Descrbing users that match a user_criteria
   *     {
   *         isMatchAll boolean 
   *         generatedMatchAllResult boolean
   *         resultQuery String
   *         hasRolesOrGroups boolean
   *         shouldHideCount boolean
   *     }
   */
  _getUsersBasedOnQueries: function(criteriaGr, checkForSingleUser, userId) {
  	var userCriteriaResult = {
  		isMatchAll: criteriaGr.match_all == 1,
  		generatedMatchAllResult: true,
  		resultQuery: "",
  		hasRolesOrGroups: false,
  		shouldHideCount: false
  	};
  	
  	if (!criteriaGr)
  		return userCriteriaResult;
  	
  	var criteriaConditions = [];
  	
  	// Support 'role' field on user_criteria
  	if (criteriaGr.getValue("role")) {
  		userCriteriaResult.hasRolesOrGroups = true;
  		if (!checkForSingleUser) {
  			userCriteriaResult.shouldHideCount = userCriteriaResult.shouldHideCount || this._userRolesExceedsLimit(criteriaGr.role.toString());
  			var resultRoleDynamicQuery = "sys_idINjavascript: new sn_hr_core.hr_BulkCaseCreation().getSysIdInRoles('" + criteriaGr.role.toString() + "',false)";
  			criteriaConditions.push(resultRoleDynamicQuery);
  		} else {
  			var userHasAnyCriteriaRole = this._userHasAnyRole(criteriaGr.role.toString(), userId);
  			if (userCriteriaResult.isMatchAll)
  				userCriteriaResult.generatedMatchAllResult = userHasAnyCriteriaRole && userCriteriaResult.generatedMatchAllResult;
  			else {
  				userCriteriaResult.generatedMatchAllResult = userHasAnyCriteriaRole;
  				return userCriteriaResult; // TODO Why are we returning early? This should only return early if it's false
  			}
  		}
  	}
  	
  	// Support 'group' field on user_criteria
  	if (criteriaGr.getValue("group")) {
  		userCriteriaResult.hasRolesOrGroups = true;
  		if (!checkForSingleUser) {
  			userCriteriaResult.shouldHideCount = userCriteriaResult.shouldHideCount || this._groupMembersExceedsLimit(criteriaGr.group.toString());
  			var resultGroupDynamicQuery = "sys_idINjavascript: new sn_hr_core.hr_BulkCaseCreation().getSysIdInGroups('" + criteriaGr.group.toString() + "',false)";
  			criteriaConditions.push(resultGroupDynamicQuery);
  		} else {
  			var userIsInAnyCriteriaGroup = this._userIsInAnyGroup(criteriaGr.group.toString(), userId);
  			if (userCriteriaResult.isMatchAll)
  				userCriteriaResult.generatedMatchAllResult = userIsInAnyCriteriaGroup && userCriteriaResult.generatedMatchAllResult;
  			else {
  				userCriteriaResult.generatedMatchAllResult = userIsInAnyCriteriaGroup;
  				return userCriteriaResult; // TODO Why are we returning early? This should only return early if it's false
  			}
  		}
  	}
  	
  	// Support 'user' field on user_criteria
  	if (criteriaGr.getValue("user"))
  		criteriaConditions.push("sys_idIN" + criteriaGr.getValue("user"));
  	
  	// Support other fields on user_criteria
  	var criteriaFields = ["company", "department", "location"];
  	for (var i = 0; i < criteriaFields.length; i++)
  		if (criteriaGr.getValue(criteriaFields[i]))
  			criteriaConditions.push(criteriaFields[i] + "IN" + criteriaGr.getValue(criteriaFields[i]));
  	
  	userCriteriaResult.resultQuery = criteriaConditions.join(userCriteriaResult.isMatchAll ? "^" : "^OR");

  	return userCriteriaResult;
  },

  /* Determine if the numbers of users in the specified groups exceeds the limit  
   *
   * @param groupSysIds String Comma separated sys_id's of Groups to count members of
   * @return boolean If there are too many users in the one of the specified @param groupSysIds
   */
  _groupMembersExceedsLimit: function(groupSysIds) {
  	if ((!gs.hasRole('sn_hr_core.content_reader') && !gs.hasRole('sn_hr_core.case_writer')) || !gs.getProperty("sn_hr_core.hideUserSelectionCriteriaCount", true))
  		return false;
  	var groupMemberGa = new GlideAggregate('sys_user_grmember');
  	groupMemberGa.addEncodedQuery('group.sys_idIN' + groupSysIds);
  	groupMemberGa.addAggregate("COUNT");
  	groupMemberGa.query();
  	if (groupMemberGa.next())
  		return groupMemberGa.getAggregate("COUNT") >= parseInt(gs.getProperty('sn_hr_core.userSelectionCriteriaCountLimit', 5000));
  	
  	return false;
  },

  /* Determine if there are too many users with one of the specified roles
   *
   * @param roleSysIds String Comma separated sys_id's of Roles to count users who have one
   * @return boolean If there are too many users with one of the specified @param roleSysIds
   */
  _userRolesExceedsLimit: function(roleSysIds) {
  	if ((!gs.hasRole('sn_hr_core.content_reader') && !gs.hasRole('sn_hr_core.case_writer')) || !gs.getProperty("sn_hr_core.hideUserSelectionCriteriaCount", true))
  		return false;
  	var userHasRoleGa = new GlideAggregate('sys_user_has_role');
  	userHasRoleGa.addEncodedQuery('state=active^role.sys_idIN' + roleSysIds);
  	userHasRoleGa.addAggregate("COUNT");
  	userHasRoleGa.query();
  	if (userHasRoleGa.next())
  		return userHasRoleGa.getAggregate("COUNT") >= parseInt(gs.getProperty('sn_hr_core.userSelectionCriteriaCountLimit', 5000));
  	
  	return false;
  },

  /* Determine if a user is a member of any of the specified groups
   *
   * @param groupSysIds String Comma separated sys_id's of Groups to check
   * @param userId String sys_id of a user
   * @return boolean If the @param userId is a member of any of the @param groupSysIds
   */
  _userIsInAnyGroup: function(groupSysIds, userId) {
  	if (!groupSysIds || !userId)
  		return false;
  	
  	var groupMemberGr = new GlideRecord('sys_user_grmember');
  	groupMemberGr.addEncodedQuery('group.sys_idIN' + groupSysIds);
  	groupMemberGr.addEncodedQuery('user.sys_id=' + userId);
  	groupMemberGr.setLimit(1);
  	groupMemberGr.query();
  	return groupMemberGr.hasNext();
  },

  /* Determine if a user has any of the specified roles
   *
   * @param roleSysIds String Comma separated sys_id's of Roles to check
   * @param userId String sys_id of a user
   * @return boolean if the @param userId has any of the @param roleSysIds
   */
  _userHasAnyRole: function(roleSysIds, userId){
  	if (!roleSysIds || !userId)
  		return false;
  	
  	var userHasRoleGr = new GlideRecord('sys_user_has_role');
  	userHasRoleGr.addEncodedQuery('state=active^role.sys_idIN' + roleSysIds);
  	userHasRoleGr.addEncodedQuery('user.sys_id=' + userId);
  	userHasRoleGr.setLimit(1);
  	userHasRoleGr.query();
  	return userHasRoleGr.hasNext();
  },

  type: 'hr_UserCriteriaEvaluation'
};

Sys ID

2cebfaa7c3033200a669d73bf3d3ae01

Offical Documentation

Official Docs: