Name
sn_hr_core.hr_Utils
Description
Generic functionality for the HR application
Script
var hr_Utils = Class.create();
hr_Utils.prototype = {
initialize : function() {
this.HR_CORE = 'sn_hr_core';
this.HR_SP = 'sn_hr_sp';
this.HR_LE = 'sn_hr_le';
this.HR_INTEGRATIONS = 'sn_hr_integrations';
this.DEFAULT_JOB_FIELDS = 'employment_type,position,position_code,office_number,location_type,offboard_type,employment_start_date,employment_end_date,notice_period,probation_period,probation_end_date,location,work_phone,work_email,manager,department';
this.JOB_DATES_MAP = {
'employment_start_date' : 'job_start_date',
'employment_end_date' : 'job_end_date'
};
},
/*
* Get list count for query
* @param
* queries: array list of string containing table and encoded query separated by single space
* example: ['table_name encoded_query']
*
* @retuns
* object containing record count for query
* example: {'query string as passed in param': integer count}
*/
getListCount: function(queries) {
var queryCounts = {};
for (var i=0; i<queries.length; i++) {
var query = queries[i];
var queryParms = query.split(' ');
var table = queryParms[0];
var encodedQuery = queryParms[1];
var count = 0;
//get row count for encoded query
var gr = new GlideAggregate(table);
gr.addAggregate('COUNT');
gr.addEncodedQuery(encodedQuery);
gr.query();
if (gr.next())
count = gr.getAggregate('COUNT');
//add resulting count for query
queryCounts[query] = count;
}
return queryCounts;
},
userHasSPClientRole : function(user){
var userId = user || gs.getUserID();
var gr = new GlideRecord('sys_user_has_role');
gr.addQuery('user', userId);
gr.addQuery('role.name','LIKE','sn_hr_sp.hrsp_%');
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
userHasHRRole : function(user) {
if(gs.nil(user))
return gs.hasRole(hr.ROLE_HR_CASE_READER);
var gr = new GlideRecord('sys_user_has_role');
gr.addQuery('user', user);
gr.addQuery('role.name', hr.ROLE_HR_CASE_READER);
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
// Used as a reference qualifier in Disciplinary issue RP variable
getHRClientUsers: function() {
return "active=true";
},
//Used as a reference qualifier in Opened For field of Case form
getOpenedForUsers: function() {
if (this.checkUserHasRole(hr.ROLE_HR_CASE_WRITER))
//return all client users if case_writer
return this.getHRClientUsers();
else {
var users = [gs.getUserID()];
return 'sys_idIN'+ users.join(',');
}
},
//Used as a reference qualifier in Subject Person field of Case form
getSubjectPersonUsers: function() {
if (this.checkUserHasRole(hr.ROLE_HR_CASE_WRITER))
//return all client users if case_writer
return this.getHRClientUsers();
else{
//return only the subordinates and himself for current user
var users = this.getHRClientSubordinateUsers(gs.getUserID());
return 'sys_idIN'+ users.join(',');
}
},
getHRClientSubordinateUsers:function(sysid){
var subusers = new sn_hr_core.hr_SysUser().getAllReports(sysid).split(',');
subusers.push(sysid);
return subusers;
},
getHRRoles:function(searchString){
var ids = [];
var gr = new GlideRecord('sys_user_role');
gr.addQuery('name','LIKE',searchString);
gr.query();
while (gr.next())
ids.push(gr.sys_id.toString());
return ids;
},
getCOEFromTopicDetails: function(topicDetailsId) {
var detailGr = new GlideRecord("sn_hr_core_topic_detail");
if (detailGr.get(topicDetailsId) && !gs.nil(detailGr.topic_category.coe))
return detailGr.topic_category.coe.toString();
return "";
},
canUpdateContact: function(){
var gr = new GlideRecord(hr.TABLE_BENEFICIARY);
if (gr.get('contact.user', previous.user)) {
//Beneficiary found but user is same returning true
if (current.user == previous.user)
return true;
else
//Beneficiary found and user is not same returning false
return false;
} else
//Beneficiary not found returning true
return true;
},
hasVIPUser: function(){
var gr = new GlideRecord('sys_user');
var q = gr.addQuery('sys_id', previous.opened_for);
q.addOrCondition('sys_id', previous.subject_person);
gr.addQuery('vip', true);
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
/*
* getRoledUsers method is getting deprecated as there is no call to this method
*/
getRoledUsers: function(queryCondition, roleListIds) {
var users = {};
var gr = new GlideRecord('sys_user_has_role');
if (roleListIds) {
gr.addQuery('role', queryCondition, roleListIds);
}
gr.query();
while (gr.next()) {
users[gr.user.toString()] = true;
}
var ids = [];
for (var id in users)
ids.push(id);
return ids;
},
getAvailableTemplates : function() {
var sysIds = '';
return sysIds;
},
userHasRole : function(user) {
var gr = new GlideRecord('sys_user_has_role');
gr.addQuery('user',user);
var qc = gr.addQuery('role.name','sn_hr_sp.hrsp_employee');
qc.addOrCondition('role.name','sn_hr_sp.hrsp_new_hire');
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
checkUserHasRole: function(role_name){
var val = gs.getProperty("sn_hr_core.include_elevated_roles", "false");
var isRolePresent = false;
if(val == 'true')
isRolePresent = gs.hasRole(role_name);
else{
var roles = gs.getUser().getRoles();
isRolePresent = roles.indexOf(role_name) > -1;
}
return isRolePresent;
},
getRolesOfUser: function(userId) {
var val = gs.getProperty("sn_hr_core.include_elevated_roles", "false");
if(val == 'true')
return this._getAllActiveRolesOfUser(userId);
else
return gs.getUser().getRoles();
},
_getAllActiveRolesOfUser: function(userId) {
var rolesList = [];
var grHasRole = new GlideRecord('sys_user_has_role');
grHasRole.addQuery('state', 'active');
grHasRole.addQuery('user', userId);
grHasRole.query();
while(grHasRole.next())
rolesList.push(grHasRole.role.name + '');
return rolesList;
},
/*
* Convenience method to prevent the code becoming unreadable from the useful debug statements
*/
_logDebug : function(str) {
if (gs.isDebugging())
gs.debug(str);
},
/**
* GlideRecordSecure does not present an issue here as we are not actually reading the record - just checking for hasNext.
* @param hrcase GlideRecord A glide record representing the HR Case.
* @return boolean True if there is a 'requested' approval record for the given case.
*/
hasApprovalPending : function(hrcase) {
var gr = new GlideRecordSecure('sysapproval_approver');
gr.addActiveQuery();
gr.addQuery('sysapproval', hrcase.sys_id);
gr.addQuery('state', 'requested');
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
canAccessManagedDoc: function(current) {
var docRevGR = new GlideRecord('dms_document_revision');
docRevGR.addActiveQuery();
docRevGR.addQuery('stage', 'published');
docRevGR.query();
var docRevs = [];
while (docRevGR.next()) {
if (this._isDocRevOwner(docRevGR))
docRevs.push(docRevGR.getUniqueValue());
}
return docRevs;
},
_isDocRevOwner: function(docRevGR) {
return (docRevGR.document.owner == gs.getUserID()) || gs.getUser().isMemberOf(docRevGR.document.owning_group.toString());
},
isWhiteListed : function(field, userId) {
if (this.checkUserHasRole(hr.ROLE_HR_PROFILE_WRITER))
return true;
// Check if the current field is present in the whitelist
var editables = hr.DEFAULT_WHITELIST;
var gr = new GlideRecord('sys_properties');
if (gr.get('name', 'sn_hr_core.hr_profile_editable_fields'))
editables = gr.value + ',';
return !gs.nil(userId) && userId == gs.getUserID()
&& this._arrayContains(editables.split(','), field);
},
_arrayContains : function(ary, seed) {
for (var i = 0; i < ary.length; i++)
if (ary[i].trim() === seed)
return true;
return false;
},
getRelevantPDFTemplates : function(record) {
var strReturn = "sys_idIN";
strReturn += this.getPDFTemplateBasedOnDocumentType(record.document_type, record.subject_person);
return strReturn;
},
/*
This method returns comma separated sys_ids of PDF Templates
matching document type and user's HR criteria
@param documentType: Document Type to filter PDF Templates
@param subjectPerson: Subject person whose HR criteria will be
checked against the HR Criteria of PDF Templates
@return Comma separated string of PDF Template sys_ids
*/
getPDFTemplateBasedOnDocumentType : function(documentType, subjectPerson){
var documentTemplates = new GlideRecord('sn_hr_core_document_template');
documentTemplates.addActiveQuery();
if (documentType)
documentTemplates.addQuery('document_type', documentType);
documentTemplates.query();
var validTemplates = [];
while (documentTemplates.next()) {
if (this._criteriaHelper(documentTemplates, subjectPerson)){
if (gs.getUserID() == 'system' || documentTemplates.canRead())
validTemplates.push(documentTemplates.getUniqueValue());
}
}
return validTemplates.join(',');
},
/*
This method returns an array of objects containing sys_id and
display value of PDF Templates matching document type and
user's HR criteria
@param documentType: Document Type to filter PDF Templates
@param subjectPerson: Subject person whose HR criteria will be
checked against the HR Criteria of PDF Templates
@return array of objects containing sys_id and display value of PDF Templates
*/
getPDFTemplateObjectsForDocumentType : function(documentType, subjectPerson){
var documentTemplates = new GlideRecord('sn_hr_core_document_template');
documentTemplates.addActiveQuery();
if (documentType)
documentTemplates.addQuery('document_type', documentType);
documentTemplates.query();
var validTemplates = [];
while (documentTemplates.next()) {
if (this._criteriaHelper(documentTemplates, subjectPerson)) {
if (gs.getUserID() == 'system' || documentTemplates.canRead()) {
var templateInfo = {};
templateInfo["sys_id"] = documentTemplates.getUniqueValue();
templateInfo["display_value"] = documentTemplates.getDisplayValue();
validTemplates.push(templateInfo);
}
}
}
return validTemplates;
},
_criteriaHelper:function(template, subject_person) {
if (template && subject_person) {
var hrCriteria = template.getValue('hr_criteria');
if (hrCriteria) {
var isValidCriteria = new hr_Criteria().evaluateById(hrCriteria+'', subject_person +'');
if (isValidCriteria) {
//If HR criteria is valid return document template
return template;
}
} else {
//If no HR Criteria, return document template
return template;
}
}
return "";
},
/*
* Convert the parameters filled into a Record Producer, into a GlideRecord. Map and fields using an
* optional map object.
*/
fillInFromMap : function(gr, parameters, map) {
// Fill in the new Profile records
for ( var key in parameters) {
var field = (map && map[key]) ? map[key] : key;
if (gr.isValidField(field))
gr.setValue(field, parameters[key]);
}
},
/*
* Convert the fields filled into a GlideRecord, into a Record Producer.
* Map and fields using an map object that is also inverted from RP -> GR map.
*/
translateFieldFromMap : function(source, fieldMap, labelMap) {
var dest = {};
var fields = this.invertMap(fieldMap);
// Fill in the new Profile records
for ( var key in source) {
var destKey = (fields && fields[key]) ? fields[key] : key;
dest[destKey] = (labelMap && labelMap[destKey]) ? labelMap[destKey] : source[destKey];
}
return dest;
},
/*
* Invert a map so that the key and value are swapped; not generalizable as this only
* works for map[String] = String;
*/
invertMap : function(inverseMap) {
var map = {};
for ( var key in inverseMap) {
var label = inverseMap[key];
map[label] = key;
}
return map;
},
getFieldsFromTable : function(table, whitelist, blacklist) {
var fieldsData = {};
var badPrefix = "sys_";
// Load the records from the passed in table directly
var grTable = new GlideRecord(table);
var elements = grTable.getElements();
var schemas = [];
for (var x = 0; x < elements.length; x++) {
var ed = elements[x].getED();
schemas.push(ed);
}
for (var i = 0; i < schemas.length; i++) {
var glideElement = schemas[i];
if ((glideElement.getName() + '').indexOf(badPrefix) !== 0)
if (this._useField(glideElement, whitelist, blacklist))
fieldsData[glideElement.getName()] = glideElement.getLabel();
}
return fieldsData;
},
_useField : function(ge, whitelist, blacklist) {
if (whitelist && whitelist[ge.getName()] === undefined)
return false;
if (blacklist && blacklist[ge.getName()] !== undefined)
return false;
return true;
},
dereferenceField : function(ref, table, column) {
var gr = new GlideRecord(table);
if (gr.get(ref))
return gr.getValue(column);
},
/* Start of Deprecated functions as of Helsinki */
/*
* Update a sn_hr_core_case record total_percent_complete field when related tasks are completed
*/
updateHRCasePercentComplete : function(gr) {
return new hr_Case().updateHRCasePercentComplete(gr);
},
generateUserName : function(first_name, last_name) {
return new hr_SysUser().generateUserName(first_name, last_name);
},
createProfileFromUser : function(userId) {
return new hr_Profile().createProfileFromUser(userId);
},
/*
* Synchronize data between the sys_user and the sn_hr_core_profile table
* @param gr - GlideRecord - The record to synchronize changes from
*/
syncProfileWithUser : function(_gr) {
new sn_hr_core.hr_Synchronize().syncRecord(gr);
},
/*
* Synchronize data between the sys_user and the sn_hr_core_profile table
* @param gr - GlideRecord - The record to synchronize changes from
*/
syncProfileFields : function(gr) {
new sn_hr_core.hr_Synchronize().syncRecord(gr);
},
/*
* Synchronises Primary job data between sn_hr_core_job (Job) table and the sn_hr_core_profile (HR Profile) table
* @param
* _gr - GlideRecord of sn_hr_core_job table
* copyAllFields - "true"/"false" to copy only changed field or all fields
* resetEmpDates - true/false to reset employment dates in HR Profile
*/
syncJobFields : function(_gr, copyAllFields, resetEmpDates) {
var tblName = _gr.getTableName();
var destGr;
var excludeFields = ['correlation_id','source']; //HR Integration fields
// Exit if not sn_hr_core_job or sn_hr_core_profile
if (tblName != hr.TABLE_JOB && tblName != hr.TABLE_PROFILE)
return null;
// Synch only Primary job data to HR Profile table
if (tblName == hr.TABLE_JOB && _gr.getValue("primary")) {
var map = resetEmpDates? this.JOB_DATES_MAP : {};
destGr = new GlideRecord(hr.TABLE_PROFILE);
if (destGr.get(_gr.getValue("hr_profile"))) {
destGr.setValue('primary_job', _gr.getUniqueValue());
return this.syncProfilesWithMap(_gr, destGr, map, excludeFields, copyAllFields);
}
}
if (tblName == hr.TABLE_PROFILE) {
destGr = this.getPrimaryJobRecord(_gr.getValue('user'));
if (!gs.nil(destGr))
return this.syncProfilesWithMap(_gr, destGr, {}, excludeFields, copyAllFields);
}
return null;
},
// Sync fields between GlideRecord objects with field map
syncProfilesWithMap : function(srcGr, destGr, map, exclusionList, copyAllFields) {
var srcFields = this._getChangedFields(srcGr, copyAllFields);
var touched = false;
var destFields = destGr.getElements();
for (var x = 0; x < destFields.length; x++) {
var element = destFields[x];
var elName = element.getName();
var isExcluded = false;
for ( var exclude in exclusionList)
if (elName == exclusionList[exclude])
isExcluded = true;
if (elName in srcFields && (!isExcluded)) {
destGr.setValue(elName, srcGr.getValue(elName)== null ? "" : srcGr.getValue(elName));
touched = true;
}
}
for ( var key in map) {
if (map[key] in srcFields) {
var keyVal= srcGr.getValue(map[key])== null ? "" : srcGr.getValue(map[key]);
destGr.setValue(key, keyVal);
touched = true;
}
}
if (touched) {
destGr.getUniqueValue();
destGr.update();
}
return destGr;
},
updateUserMismatchField : function(srcField, srcGr, destGr, copyAllFields) {
var srcValue = srcGr.getValue(srcField);
if (srcValue) {
var touched = false;
var srcFieldChanges = this._getChangedFields(srcGr);
if (srcField == "title" && (srcField in srcFieldChanges || copyAllFields == 'true')) {
var position = new GlideRecord("sn_hr_core_position");
if (position.get("position", srcGr.title)) {
destGr.setValue('position', position.sys_id);
touched = true;
} else
gs.warn("[hr_Utils] User title '" + srcGr.title + "' does not exist in sn_hr_core_position");
}
if (srcField == "country" && (srcField in srcFieldChanges || copyAllFields == 'true')) {
var country = new GlideRecord("core_country");
country.get("iso3166_2", srcGr.country); // iso3166_2 is column name for country code in country table.
destGr.setValue("country", country.sys_id);
touched = true;
}
if (touched) {
destGr.setWorkflow(false);
destGr.getUniqueValue();
destGr.update();
}
}
},
/*
* Create a job record in sn_hr_core_job table for the user
* @param
* srcGr - source glide record, i.e sn_hr_core_profile
* @return
* primary job sys_id or null
*/
createPrimaryJobFromProfile: function(srcGr) {
var retJobId = '';
var userId = srcGr.getValue('user');
var jobFields = gs.getProperty('sn_hr_core.hr_profile_job_fields', this.DEFAULT_JOB_FIELDS).split(',');
var destGr = new GlideRecord(hr.TABLE_JOB);
destGr.initialize();
destGr.setValue('primary', true);
destGr.setValue('hr_profile', srcGr.getValue('sys_id'));
destGr.setValue('user', userId);
for (var i = 0; i < jobFields.length; i++) {
var elName = jobFields[i];
if(elName == 'manager' || elName == 'department' || elName == 'location') //Primary Job related fields in User record
destGr.setValue(elName, srcGr.user[elName]);
else
destGr.setValue(elName, srcGr.getValue(elName));
}
destGr.setValue('job_start_date', srcGr.getValue('employment_start_date'));
destGr.setValue('job_end_date', srcGr.getValue('employment_end_date'));
retJobId = destGr.insert();
if(gs.nil(retJobId))
retJobId = this.getPrimaryJob(userId);
return retJobId;
},
/*
* Create a job record in sn_hr_core_job table for the user
* @params
* profileGr - HR Profile glide record, i.e sn_hr_core_profile
* parameters - questions from Record producer
* isPrimary - boolean, create primary or non-primary job
* @return
* new job sys_id or null
*/
createJobFromParameters: function(profileGr, parameters, isPrimary) {
var hrProfileId = profileGr.getUniqueValue();
var userId = profileGr.getValue('user');
//Set parameters for fields like hr_profile, user, primary in Jobs tables
parameters['hr_profile'] = hrProfileId;
parameters['user'] = userId;
parameters['primary'] = (gs.nil(this.getPrimaryJob(userId)) || isPrimary)? true : false;
var grJob = new GlideRecord('sn_hr_core_job');
grJob.initialize();
this.fillInFromMap(grJob, parameters, this.JOB_DATES_MAP);
return grJob.insert();
},
/*
* Get the primary job from sn_hr_core_job table for the user
* @param
* userId - user sys_id
* @return
* primary job sys_id or null
*/
getPrimaryJob: function(userId) {
if(!userId)
return null;
var primaryJobGr = this.getPrimaryJobRecord(userId);
return !gs.nil(primaryJobGr)? primaryJobGr.getUniqueValue() : null;
},
/*
* Switch the primary job of the user
* @params
* userId - User sys_id from sys_user
* jobId - Job sys_id from sn_hr_core_job
* @return
* encoded json with status and message
*/
switchPrimaryJob: function(userId, jobId) {
//Validations
if(gs.nil(userId)) {
this._logDebug('[hr_Utils] switchPrimaryJob: User input is null');
return this._getStatusMsg('error', gs.getMessage('User input to switch primary job is null'));
}
if(gs.nil(jobId)) {
this._logDebug('[hr_Utils] switchPrimaryJob: Job input is null');
return this._getStatusMsg('error', gs.getMessage('Job input to switch primary job is null'));
}
//Gets the current primary job and set the primary flag to false
var currentPrimaryJob = this.getPrimaryJob(userId);
if(!gs.nil(currentPrimaryJob)) {
var isPrimaryJobDisabled = this.setPrimaryFieldForJob(currentPrimaryJob, false);
if(!isPrimaryJobDisabled)
return this._getStatusMsg('error', gs.getMessage("Disabling existing primary job of the user failed"));
}
//Set the primary flag to true for the job in the parameter
var isPrimaryJobSwitched = this.setPrimaryFieldForJob(jobId, true);
if(isPrimaryJobSwitched)
return this._getStatusMsg('success', gs.getMessage("Switched primary job for the user successfully"));
else {
this.setPrimaryFieldForJob(currentPrimaryJob, true); //Fallback to prior primary job, as switching primary job failed
return this._getStatusMsg('error', gs.getMessage("Switching primary job for the user failed"));
}
},
/*
* Enables/Disables a job as primary for the user in sn_hr_core_job table
* @param
* jobId - job id of the user
* isPrimary - true/false
* @return
* boolean - On successful update, return true else false
*/
setPrimaryFieldForJob: function(jobId, isPrimary) {
if(!jobId)
return false;
var grJob = new GlideRecord('sn_hr_core_job');
if(grJob.get(jobId)) {
grJob.setValue('primary', isPrimary);
return gs.nil(grJob.update())? false: true;
}
this._logDebug('[hr_CaseUtils] setPrimaryFieldForJob: The job with sys_id: ' + jobId + ' is not in the Jobs table');
return false;
},
/*
* Get the primary job GlideRecord from sn_hr_core_job table for the user
* @param
* userId - user sys_id
* @return
* primary job GlideRecord or null
*/
getPrimaryJobRecord: function(userId) {
if(!userId)
return null;
var grJob = new GlideRecord('sn_hr_core_job');
grJob.addQuery('primary', true);
grJob.addQuery('user', userId);
grJob.setLimit(1);
var grJobOR = grJob.addNullQuery('job_end_date');
grJobOR.addOrCondition('job_end_date', '>=', 'javascript:gs.beginningOfToday()');
grJob.addNotNullQuery('job_start_date');
grJob.orderBy('job_start_date');
grJob.query();
if(grJob.next())
return grJob;
this._logDebug('[hr_CaseUtils] getPrimaryJobRecord: The user with sys_id: ' + userId + ' does not have a primary job record in Job table');
return null;
},
_updateProfileMismatchField : function(srcField, srcGr, destGr) {
var srcValue = srcGr.getValue(srcField);
if (srcValue) {
var touched = false;
var srcFieldChanges = this._getChangedFields(srcGr);
if (srcField == "position" && srcField in srcFieldChanges) {
var destTitleValue = new GlideRecord("sn_hr_core_position");
if (destTitleValue.get(srcValue)) {
destGr.setValue("title", destTitleValue.getDisplayValue());
touched = true;
}
}
if (srcField == "country" && srcField in srcFieldChanges) {
var destValue = new GlideRecord("core_country");
if (destValue.get(srcValue)) {
destGr.setValue("country", destValue.iso3166_2); // iso3166_2 is column name for country code in country table.
touched = true;
}
}
if (touched) {
destGr.getUniqueValue();
destGr.update();
}
}
},
/*
* Return an array containing elements of a GlideRecord that
* have changed. Do not return calculated fields
*/
_getChangedFields : function(srcGr, copyAllFields) {
var changed = {};
var fields = srcGr.getElements();
for (var x = 0; x < fields.length; x++) {
var element = fields[x];
if (copyAllFields == 'true' || element.changes()) {
var elName = element.getName();
if (!element.getED().isVirtual() && !elName.startsWith('sys_'))
changed[elName] = element;
}
}
return changed;
},
maskSSN : function(str) {
if (gs.nil(str))
return "";
//Remove the unwanted special characters
str = this.sanitize(str);
var trailingCharsIntactCount = 4;
str = str.toString();
var newstr = str;
if (str.length > 4) {
newstr = str.substring(0, str.length - trailingCharsIntactCount);
newstr = newstr.replace(/./g, 'x') + str.slice(-trailingCharsIntactCount);
}
return newstr;
},
/**
* Remove the unwanted speacial characters from the String
* Characters inside regex array will be removed from string.
*/
sanitize : function(str){
var cleanStr = str.replace(/[-()]/g,'');
return cleanStr;
},
getDocRevisionInfoByDocumentId : function(docId) {
var docRevision = null;
var gr = new GlideRecord("dms_document_revision");
gr.addQuery("document", docId);
gr.addQuery("stage", "published");
gr.query();
if (gr.next() && gr.canRead()) {
docRevision = {};
var info = this.getAttachmentInfo("dms_document_revision", gr.getUniqueValue());
docRevision.filename = this.getDocumentNameById(docId);
docRevision.href = "/sys_attachment.do?sys_id=" + info.sys_id;
docRevision.contentType = info.content_type;
docRevision.bytes = info.size_bytes;
}
return docRevision;
},
getDocumentNameById : function(docId) {
var gr = new GlideRecord("dms_document");
if (gr.get(docId))
return gr.getValue("name");
},
getAttachmentInfo : function(tableName, tableSysId) {
var gr = new GlideRecord("sys_attachment");
gr.addQuery("table_name", tableName);
gr.addQuery("table_sys_id", tableSysId);
gr.setLimit(1);
gr.query();
var info = {};
if (gr.next()) {
info.sys_id = gr.getUniqueValue();
info.size_bytes = gr.getValue("size_bytes");
info.content_type = gr.getValue("content_type");
}
return info;
},
/**
* Get the (actual) duration, between startTime and endTime
*/
calcDuration : function(/* GlideDateTime or String */startTime, /* GlideDateTime or String */endTime) {
if (!startTime || !endTime)
return 0;
endTime = new GlideDateTime(endTime);
startTime = new GlideDateTime(startTime);
var offsetEndTime = endTime.getTZOffset();
var offsetStartTime = startTime.getTZOffset();
return Math.floor((endTime.getNumericValue() + offsetEndTime) / 1000) - Math.floor((startTime.getNumericValue() + offsetStartTime) / 1000);
},
/**
* Determine if a user can read HR Tables by checking if they have any HR roles
* @return boolean - Whether a user can read any HR Tables
*/
canReadHRTables : function() {
if (gs.getProperty('sn_hr_core.include_elevated_roles', 'false') == 'true') {
var grHasRole = new GlideRecord('sys_user_has_role');
grHasRole.addQuery('state', 'active');
grHasRole.addQuery('user', gs.getUserID());
grHasRole.addQuery('role.name', 'STARTSWITH', hr.ROLE_HR_ANY);
grHasRole.setLimit(1);
grHasRole.query();
return grHasRole.hasNext();
} else {
var roles = gs.getUser().getRoles();
for (var i = 0;i < roles.length; i++)
if (roles[i].indexOf(hr.ROLE_HR_ANY) == 0)
return true;
return false;
}
},
addUserRole: function(role, userSysId) {
if(this.isHRRole(role)){
var gr = new GlideRecord('sys_user_has_role');
gr.initialize();
gr.user = userSysId;
gr.role = role;
var res = gr.insert();
if(!res)
gs.addErrorMessage(gs.getMessage("Your role does not allow assignment of {0} role", this._getRoleName(role)));
}
},
isHRRole: function(role){
var gr = new GlideRecord('sys_user_role');
gr.addQuery('sys_id', role);
gr.addQuery('name', 'STARTSWITH', 'sn_hr_');
gr.setLimit(1);
gr.query();
return gr.hasNext();
},
// Removes all core roles and portal roles.
removeRolesAssigned:function(userSysId){
var answer = [];
var gr = new GlideRecord('sys_user_role');
var gc = gr.addQuery('name', 'STARTSWITH', "sn_hr_core.hrsm");
gc.addOrCondition('name', 'STARTSWITH', "sn_hr_sp.hrsp");
gr.query();
while (gr.next()) {
answer.push(gr.getValue('name'));
}
if(answer.length > 0){
new global.HRSecurityUtilsAjax().removeUserRoles(userSysId, answer.join(','));
}
},
// Assigns roles based on condition mentioned in HR condition table
matchingPortalRoles:function(current){
var userSysId = current.user.sys_id;
var conditions = this._matchingPortalRolesCondition('sn_hr_core_client_role_rule');
for (var i = 0; i < conditions.length; i++) {
var bool = GlideFilter.checkRecord(current, conditions[i].conditions);
if (bool) {
var hasRole = this._checkIsRolePresent(userSysId, conditions[i].roleName);
if(hasRole){
this.addUserRole(conditions[i].roleName, userSysId);
}
}
}
},
// Checks whether user already has role. If he has core role it will remove and assign portal role if service portal is enabled.
_checkIsRolePresent:function(userSysId,role){
var hasRole = new GlideRecord('sys_user_has_role');
var roleName = this._getRoleName(role);
if(roleName.indexOf("hrsm") > -1){
roleName = roleName.replace("core.hrsm","sp.hrsp");
hasRole.addQuery('user.sys_id',userSysId);
hasRole.addQuery('role.name',roleName);
hasRole.query();
while(hasRole.next()){
return false;
}
return true;
}
if(roleName.indexOf("hrsp") > -1){
roleName = roleName.replace("sp.hrsp","core.hrsm");
hasRole.addQuery('user.sys_id',userSysId);
hasRole.addQuery('role.name',roleName);
hasRole.query();
while(hasRole.next()){
new global.HRSecurityUtilsAjax().removeUserRoles(userSysId,role);
}
return true;
}
return false;
},
// Gets role name from role sys_id.
_getRoleName:function(role){
var roleName = new GlideRecord('sys_user_role');
roleName.addQuery('sys_id',role);
roleName.setLimit(1);
roleName.query();
if(roleName.next()){
return roleName.name;
}
},
_matchingPortalRolesCondition:function(table) {
var criteria = new GlideRecord(table);
var conditions = [];
criteria.addQuery('active', 'true');
criteria.query();
while (criteria.next()) {
var condition = criteria.condition.condition.toString();
var role = criteria.role.toString();
conditions.push({conditions: condition,roleName: role});
}
return conditions;
},
// Assigns new role based on new condition.
assignRolesPerCondition:function(condition,role){
var user = new GlideRecord('sn_hr_core_profile');
user.addEncodedQuery(condition);
user.query();
while(user.next()){
var bool = this._checkIsRolePresent(user.user.sys_id,role);
if(bool){
this.addUserRole(role,user.user.sys_id);
}
}
},
// Removes previously assigned roles based on previous condition.
removePreviouslyAssignedRoles:function(condition,roleName){
var user = new GlideRecord('sn_hr_core_profile');
user.addEncodedQuery(condition);
user.query();
while(user.next()){
new global.HRSecurityUtilsAjax().removeUserRoles(user.user.sys_id,roleName);
}
},
/* Get list of active cases the user has been requested to approve
* @param userId String sys_id of user
* @return String csv of case sys_id's the user has an approval for
*/
getCaseSysIdListForApprovals: function(userId) {
var caseSysIdList = [];
if (gs.nil(userId) || userId == 'NULL')
return caseSysIdList.toString();
var approvers = this.getApprovals(userId);
var sysApprovalGR = new GlideRecord('sysapproval_approver');
sysApprovalGR.addQuery("state", "!=", "not requested");
sysApprovalGR.addNotNullQuery("sysapproval");
sysApprovalGR.addQuery("sysapproval.active", true);
sysApprovalGR.addQuery("sysapproval.sys_class_name", "INSTANCEOF", "sn_hr_core_case");
var query = sysApprovalGR.getEncodedQuery();
var qc = sysApprovalGR.addQuery('approver', approvers);
// Support granular delegation if available
if (GlidePluginManager().isActive('com.glide.granular_service_delegation')) {
if (approvers && approvers.length > 1) {
qc.addOrCondition('sys_id', 'IN', new hr_Delegation().getDelegatedApprovals({ encoded_query: query }, userId, false)); // Support old delegation with granular delegation
sysApprovalGR.query();
} else
sysApprovalGR = new hr_Delegation().getDelegatedApprovalsGR({ encoded_query: query }, userId, true); // Use API to get assigned and delegated approvals to prevent extra query
} else
sysApprovalGR.query();
while (sysApprovalGR.next())
caseSysIdList.push(sysApprovalGR.getValue('sysapproval'));
return caseSysIdList.toString();
},
getApprovals: function(userId) {
var approvalsKey = 'userApprovals';
if (hr_Utils.hasOwnProperty(approvalsKey) && !gs.nil(hr_Utils[approvalsKey]) && hr_Utils[approvalsKey].hasOwnProperty(userId))
return hr_Utils[approvalsKey][userId];
hr_Utils[approvalsKey] = {};
var userIds = [new String(userId)];
var grDelegate = new GlideRecord("sys_user_delegate");
grDelegate.addQuery("delegate", userId);
grDelegate.addQuery("approvals", true);
grDelegate.addQuery("starts", "<=", gs.daysAgo(0));
grDelegate.addQuery("ends", ">=", gs.daysAgo(0));
grDelegate.query();
while (grDelegate.next())
userIds.push(grDelegate.getValue('user'));
hr_Utils[approvalsKey][userId] = userIds;
return userIds;
},
/* Get a list of case sys_id's for task assignee
* @param userId {String} (optional) The user sys_id to use for querying
* @param parentId {String} (optional) The case sys_id to use for querying
* @return {String} The list of parent sys_id's for the task assignee
*/
getCaseSysIdForTaskAssignee : function(userId, parentId){
var caseMap = {};
if (gs.nil(userId) || userId == 'NULL')
return caseSysIdList.toString();
var hrTask = new GlideRecord('task');
// Use property to help reduce the total number of cases returned in the query
var queryLimitMonths = gs.getProperty('sn_hr_core.restrict_query.limit_inactive', '');
if (queryLimitMonths !== '' && !isNaN(queryLimitMonths) && Number(queryLimitMonths) > -1)
hrTask.addQuery('active=true^ORsys_updated_onRELATIVEGT@month@ago@' + Number(queryLimitMonths));
if(GlidePluginManager.isActive('com.snc.document_templates'))
hrTask.addQuery('sys_class_name','IN','sn_hr_core_task, sn_doc_task');
else
hrTask.addQuery('sys_class_name', 'sn_hr_core_task');
hrTask.addNotNullQuery('parent');
if (parentId)
hrTask.addQuery('parent', parentId);
// Use the current encoded query to add delegated record sys_id's
if (GlidePluginManager().isActive('com.glide.granular_service_delegation')) {
var grDelegations = new sn_delegation.DelegationUtil().getDelegatedAssignmentsForUser(userId, false, { encoded_query: hrTask.getEncodedQuery() });
while (grDelegations.next())
caseMap[grDelegations.getValue('parent')] = true;
}
hrTask.addQuery('assigned_to', userId);
hrTask.query();
while (hrTask.next())
caseMap[hrTask.getValue('parent')] = true;
// Return only unique sys_id's
var caseList = [];
for (var key in caseMap)
caseList.push(key);
return caseList.toString();
},
/*
* Returns the portal page to redirect to for hr service, sc catalog and order guide task types
*/
ticketPage: function() {
if (new GlidePluginManager().isActive('com.sn_hr_service_portal'))
return new sn_hr_sp.hr_PortalUtil().ticketPage();
},
cleanupChildRecordsForCase: function(grCase) {
if(gs.nil(grCase) || !grCase.isValidRecord())
throw new Error("Unable to close the child records since the HR case is invalid");
var closeNotes = grCase.getValue("close_notes");
var grChildCase = new GlideRecord('sn_hr_core_case');
grChildCase.addQuery('parent', grCase.sys_id);
grChildCase.addActiveQuery();
grChildCase.query();
while(grChildCase.next()) {
grChildCase.setValue('state', hr_Constants.CASE_CANCELLED);
if (!gs.nil(closeNotes))
grChildCase.setValue('close_notes', closeNotes);
grChildCase.update();
}
var grChildTask = new GlideRecord('sn_hr_core_task');
grChildTask.addQuery('parent', grCase.sys_id);
grChildTask.addActiveQuery();
grChildTask.query();
while(grChildTask.next()) {
grChildTask.setValue('state', hr_Constants.TASK_CLOSED_INCOMPLETE);
grChildTask.setValue('work_notes', 'Automatically closed because parent case was cancelled');
if (!gs.nil(closeNotes))
grChildTask.setValue('close_notes', closeNotes);
grChildTask.update();
}
},
isEdgeEncryptionActive : function(table, sys_id) {
var gr = new GlideRecord(table);
gr.get(sys_id);
return gr.getED().hasAttachmentsEncrypted() && !gs.isEdgeEncryptedSession();
},
hasAttachments : function(record) {
var gr = record || this._gr;
if (gr) {
var grAttachment = new GlideRecord('sys_attachment');
grAttachment.addQuery('table_name', gr.getRecordClassName());
grAttachment.addQuery('table_sys_id', gr.getUniqueValue());
grAttachment.setLimit(1);
grAttachment.query();
return grAttachment.hasNext();
}
return false;
},
resetCOEConfig: function() {
new sn_hr_core.hr_license().resetCOEConfig();
},
/*
* The method is to enable all UA Entitlements
* The flags Active and User Override will be turned true for all Entitlement belonging to an Application
* If the User Override == true,
* Skip record
* Else
* If Active == true
* Update User Override = true
* Else
* Enable all assets of the entitlement in all scopes (HR Core, HR LE, HR SP, HR Integrations)
*
* Update the Inactive tables property
*
* @param appId - Application ID (For ex: com.sn_hr_core, com.sn_hr_lifecycle_events)
*/
enableAllEntitlements: function(appId) {
var currInactiveTables = gs.getProperty("sn_hr_core.inactive_tables", "");
var tablesToMakeActive = '';
var grEntitlement = new GlideRecord('ua_entitlement');
grEntitlement.addQuery('user_override', false);
grEntitlement.addQuery('app_id', appId);
grEntitlement.query();
while(grEntitlement.next()) {
if(grEntitlement.active){
grEntitlement.setValue('user_override', true);
grEntitlement.update();
} else {
this._enableAssetsInAllScopes(grEntitlement.getValue('id'));
tablesToMakeActive += grEntitlement.getValue('table_names');
tablesToMakeActive += ',';
}
}
if(!gs.nil(currInactiveTables) && !gs.nil(tablesToMakeActive))
this._updateInactiveTablesProperty(currInactiveTables, tablesToMakeActive);
},
/*
* The method is to enable all assets for the particular entitlement id
* Call to Usage Analytics API - sn_lef.GlideEntitlement.enableEntitlement(<entitlement>, <scope>, <disableWorkFlow>)
*
* The call to this API result in enabling assets like Record producers, HR Services, Modules, Topic Cateogries, Topic Detail, Templates
* The call also updates the Active field = true and User override = true for the entitlement in the ua_entitlement table
*
* @param entitlementId (For ex: hr_payroll, hr_total_rewards etc.)
*/
_enableAssetsInAllScopes: function(entitlementId) {
if(GlidePluginManager.isActive('com.sn_hr_core'))
sn_lef.GlideEntitlement.enableEntitlement(entitlementId, this.HR_CORE, true);
if(GlidePluginManager.isActive('com.sn_hr_integrations'))
sn_lef.GlideEntitlement.enableEntitlement(entitlementId, this.HR_INTEGRATIONS, true);
if(GlidePluginManager.isActive('com.sn_hr_service_portal'))
sn_lef.GlideEntitlement.enableEntitlement(entitlementId, this.HR_SP, true);
if(GlidePluginManager.isActive('com.sn_hr_lifecycle_events'))
sn_lef.GlideEntitlement.enableEntitlement(entitlementId, this.HR_LE, true);
},
/*
* The method updates the system property sn_hr_core.inactive_tables
* For new customers, the below method will not be called
* For upgrading customers, if any custom table is added in the property - it is preserved
*
* @param currInactiveTables - current list of tables in Inactive table property
* @param tablesToMakeActive - new list of tables that has to be removed from inactive table property
*/
_updateInactiveTablesProperty: function(currInactiveTables, tablesToMakeActive) {
var currTablesArry = currInactiveTables.split(',');
var activesTableArry = tablesToMakeActive.split(',');
var updatedTablesProp = this._getDiffArray(currTablesArry, activesTableArry).join(',');
gs.setProperty("sn_hr_core.inactive_tables", updatedTablesProp);
},
//Return A - B in the arrays
_getDiffArray: function(xArray, yArray) {
return xArray.filter(function(item) {return yArray.indexOf(item) < 0;});
},
/*
* Method returns json object with properties - 'status' and 'message'
*
* @param
* status - status of the result, for ex: 'success', 'error'
* message - status message
* @return
* encoded JSON
*/
_getStatusMsg: function(status, message) {
var retResult = {};
retResult['status'] = status;
retResult['message'] = message;
return new global.JSON().encode(retResult);
},
upgradeFulfillmentType : function() {
var hrServiceWithLE = false;
var hrServiceWithJourney = false;
var hrServiceWithApprovers = false;
var hrServiceWithActivities = false;
var hrServiceWithWorkflow = false;
var resultWF;
copyApprovalOptions();
function copyApprovalOptions() {
var gr = new GlideRecord('sn_hr_core_service_activity');
if (!gr.isValidField('approval_options'))
return;
gr.addQuery('activity_type', 'approval');
gr.addNullQuery('approval_options');
gr.addNotNullQuery('parent_service.approval_options');
gr.query();
while (gr.next()) {
gr.approval_options = gr.parent_service.approval_options;
gr.update();
}
}
var hrServiceListWithActivities = getHrServicesWithActivities();
var hrService = new GlideRecord('sn_hr_core_service');
hrService.addQuery('sys_scope','532da270dad21200a4656ede91f9331e');
hrService.query();
while (hrService.next()) {
getConditions(hrService);
setHRServiceType(hrService);
resetConditions();
}
function getHrServicesWithActivities() {
var hrServicesWithActivities = {};
var grHRServiceActivity = new GlideAggregate("sn_hr_core_service_activity");
grHRServiceActivity.groupBy("parent_service");
grHRServiceActivity.query();
while (grHRServiceActivity.next())
hrServicesWithActivities[grHRServiceActivity.parent_service.sys_id] = true;
return hrServicesWithActivities;
}
function getConditions(grHRService) {
if (grHRService.le_type != undefined && grHRService.le_type != '')
hrServiceWithLE = true;
if (grHRService.journey_config != undefined && grHRService.journey_config != '')
hrServiceWithJourney = true;
if (grHRService.approval_options != undefined && grHRService.approval_options != '')
hrServiceWithApprovers = true;
if (hrServiceListWithActivities[grHRService.sys_id] != undefined)
hrServiceWithActivities = true;
getWorkflow(grHRService.template);
}
function setHRServiceType(grHRService) {
if (hrServiceWithLE && hrServiceWithActivities)
grHRService.setValue('fulfillment_type', "custom");
else if (hrServiceWithLE && (hrServiceWithApprovers))
grHRService.setValue('fulfillment_type', "custom");
else if (hrServiceWithActivities && (hrServiceWithApprovers))
grHRService.setValue('fulfillment_type', "custom");
else if (hrServiceWithActivities)
grHRService.setValue('fulfillment_type', "service_activity");
else if (hrServiceWithJourney)
grHRService.setValue('fulfillment_type', 'journey');
else if (hrServiceWithLE)
grHRService.setValue('fulfillment_type', "lifecycle_event");
else if (hrServiceWithApprovers && hrServiceWithWorkflow) {
grHRService.setValue('fulfillment_type', "custom");
grHRService.setValue('workflow_detail',resultWF);
} else if(hrServiceWithWorkflow){
grHRService.setValue('fulfillment_type', "workflow");
grHRService.setValue('workflow_detail',resultWF);
} else if(hrServiceWithApprovers){
grHRService.setValue('fulfillment_type', "custom");
} else
grHRService.setValue('fulfillment_type', "simple");
grHRService.setWorkflow(false);
grHRService.update();
}
function resetConditions() {
hrServiceWithLE = false;
hrServiceWithJourney = false;
hrServiceWithApprovers = false;
hrServiceWithActivities = false;
hrServiceWithWorkflow = false;
}
function getWorkflow(templateSysId){
var validateWF =new sn_hr_core.hrFulfillmentTypeUtil();
resultWF = validateWF.getWorkflow(templateSysId);
if (resultWF !='')
hrServiceWithWorkflow = true;
}
},
setAssignmentType : function() {
var grTemplate = new GlideRecord('sn_hr_core_template');
// LE Scope Specific tables
grTemplate.addEncodedQuery('sys_scope=532da270dad21200a4656ede91f9331e');
grTemplate.addQuery('table','!=','sn_hr_core_task');
grTemplate.query();
while(grTemplate._next()){
var grTemplateInfo = grTemplate.template.toString();
var assignedToIdx = grTemplateInfo.indexOf("assigned_to");
var skillIdx = grTemplateInfo.indexOf("skills");
var assignmentGroupIdx = grTemplateInfo.indexOf("assignment_group");
if (assignedToIdx > -1)
grTemplate.assignment_option = 'named_user';
else if (skillIdx > -1 || assignmentGroupIdx > -1)
grTemplate.assignment_option = 'skills_group';
else
grTemplate.assignment_option = '';
grTemplate.setWorkflow(false);
grTemplate.update();
}
},
/*
* Return value of 'global description' field if populated, else
* value of 'description' field
*
* @param {GlideRecord} gr - an HR Case or HR Task record
*
* @returns {(string|undefined)} the description value, undefined if not passed a GlideRecord
*/
getDescription: function(gr) {
if (!gr || typeof gr.getValue !== 'function')
return;
if( gr.template && gr.template.show_translated_fields)
return gr.getDisplayValue("template.description_for_employee");
return gr.getValue("rich_description") || GlideStringUtil.escapeHTML(gr.getValue("description"));
},
/*
* Return value of 'rich_description' field if populated, else
* value of 'description' field
*
* @param {GlideRecord} gr - an HR Case or HR Task record
*
* @returns {(string|undefined)} the description value, undefined if not passed a GlideRecord
*/
getNonGlobalCaseDescription: function(gr) {
if (!gr || typeof gr.getValue !== 'function')
return;
return gr.getValue("rich_description") || GlideStringUtil.escapeHTML(gr.getValue("description"));
},
/*
* Returns application scope for table
*
* @param
* table: string table name
*
* @returns
* success: string value of scope
* failure: empty string
*/
getTableScope: function(table) {
var tableScope = '';
var tableRecord = new GlideRecord('sys_db_object');
tableRecord.addQuery('name', table);
tableRecord.setLimit(1);
tableRecord.query();
if (tableRecord.next())
tableScope = tableRecord.sys_scope;
return tableScope;
},
/*
Wrapper to getAcknowledgeDocument in esign_taskUtils
*/
getAcknowledgeDocument: function(acknowledgeDocument) {
return new sn_esign.esign_taskUtils().getAcknowledgeDocument(acknowledgeDocument);
},
/* Methods to trigger after the case cancelled or close complete by BR - Cancel or Close Case Cleanup
*/
/* Function closes child tasks,cases, approvals, requested items and workflows associated with given parent case
@params
grCase - gliderecord of sn_hr_core_case
actionName - which action triggered case closure.
@return
-
*/
onCaseClose : function(grCase, actionName) {
if (gs.nil(grCase) || !grCase.isValidRecord())
throw new Error("Unable to close the case since the HR case is invalid");
this._renderTaskApprovalsMoot(grCase);
if(GlidePluginManager.isActive('com.sn_hr_lifecycle_events'))
// Cancel activity set contexts before canceling the WF to set the context state to 'cancelled'.
new sn_hr_le.hr_ActivitySetContextUtil().cancelActivitySetContextsFromCase(grCase.getUniqueValue(), grCase.getValue('state'));
this.cancelMyWorkflows(grCase, actionName);
this._cancelRequestedItems(grCase);
if(GlidePluginManager.isActive('com.sn_lnp'))
this._cancelLearningTasks(grCase,actionName);
//Schedule asynchronous cleanup if the user may not have access to child cases/tasks
if (gs.getUser().getName() == 'system' || new hr_Utils().checkUserHasRole(hr.ROLE_HR_CASE_READER))
this.cleanupChildRecordsForCase(grCase);
else
gs.eventQueue('sn_hr_core.case_cleanup', grCase);
},
_renderTaskApprovalsMoot : function(grCase) {
if(gs.nil(grCase) || !grCase.isValidRecord())
throw new Error("Invalid input parameter");
var gr = new GlideRecord('sysapproval_approver');
gr.addQuery('sysapproval', grCase.sys_id);
var qc = gr.addQuery('state', 'requested');
qc.addOrCondition('state', 'not requested');
gr.setValue('state', 'not_required');
gr.updateMultiple();
},
cancelMyWorkflows : function(grCase, actionName) {
if(gs.nil(grCase) || !grCase.isValidRecord())
throw new Error("Invalid input parameter");
var wf = new global.Workflow();
var gr = wf.getRunningFlows(grCase);
while (gr.next())
wf.cancelContext(gr);
},
_cancelLearningTasks : function(grCase,actionName) {
new sn_lc.LearningTaskUtils().closeChildTasks(grCase,actionName);
},
_cancelRequestedItems : function(grCase) {
if(gs.nil(grCase) || !grCase.isValidRecord())
throw new Error("Invalid input parameter");
var closeNotes = grCase.getValue("close_notes");
var grRequest = new GlideRecord('sc_request');
grRequest.addQuery('parent', grCase.sys_id);
grRequest.addActiveQuery();
grRequest.query();
while(grRequest.next()) {
grRequest.setValue('request_state', 'closed_cancelled');
if (!gs.nil(closeNotes)) {
grRequest.setValue('close_notes', closeNotes);
var grRequestItem = new GlideRecord('sc_req_item');
grRequestItem.addQuery('request', grRequest.getUniqueValue());
grRequestItem.query();
grRequestItem.setValue('close_notes', closeNotes);
grRequestItem.updateMultiple();
}
grRequest.update();
}
},
canRenderUIAction :function(caseGr,actionName)
{
if(caseGr.sys_class_name!="sn_hr_er_case")
return true;
return new sn_hr_er.er_SecurityUtils().canRenderUIAction(caseGr,actionName);
},
/* Function to check if adhoc approval action can be shown
@params
caseGr - gliderecord of sn_hr_core_case
@return
true - if action can be shown
false- if action can not be shown
*/
canShowAdhocApprover : function(caseGr)
{
return hr_ApprovalUtil.isAdhocApprovers(caseGr);
},
isExtendedFromCase: function(table) {
var tableHierarchy = hr.TABLE_CASE_EXTENSIONS;
return tableHierarchy.indexOf(table) !== -1;
},
/*
Funtion to check whether we can copy attachments or not
@param table name
*/
canCopyAttachments: function(table) {
// return true to allow copy of attachments from interaction to case
return this.isExtendedFromCase(table);
},
type : 'hr_Utils'
};
hr_Utils.initializeQueryVariables = function() {
hr_Utils.instance = new hr_Utils();
hr_Utils.userID = gs.getUserID();
delete hr_Utils['myCasesWithApprovals'];
delete hr_Utils['myCasesWithTasks'];
hr_Utils.getMyGroups = function() {
return gs.getUser().getMyGroups();
};
hr_Utils.getMyCasesWithApprovals = function() {
if(!hr_Utils.hasOwnProperty('myCasesWithApprovals'))
hr_Utils['myCasesWithApprovals'] = hr_Utils.instance.getCaseSysIdListForApprovals(gs.getUserID());
return hr_Utils['myCasesWithApprovals'];
};
hr_Utils.getMyCasesWithTasks = function() {
if(!hr_Utils.hasOwnProperty('myCasesWithTasks'))
hr_Utils['myCasesWithTasks'] = hr_Utils.instance.getCaseSysIdForTaskAssignee(gs.getUserID());
return hr_Utils['myCasesWithTasks'];
};
};
hr_Utils.initializeQueryVariables();
Sys ID
f65370019f22120047a2d126c42e7000