Name
sn_hr_core.hr_BulkCaseRequestUtils
Description
No description available
Script
var hr_BulkCaseRequestUtils = Class.create();
hr_BulkCaseRequestUtils.prototype = {
initialize: function() {},
/**
* Checks if
* 1. 'Bulk case request' status is 'requested'
* 2. ALL `user-segment-groups` are processed and
* 3. has atleast one `user-segment` in `included` state
*
* @param {string} bulkCaseRequestID - sn_hr_core_bulk_case_request record sys_id
*
* @return {boolean}
*
* throws exception
*/
canCreateBulkCases: function(bulkCaseRequestID) {
try {
if (gs.nil(bulkCaseRequestID))
throw this.getError("canCreateBulkCases' - missing sn_hr_core_bulk_case_request sys_id.");
//return false immediately if 'Bulk case request' state is not 'requested'
var bulkCaseRequestGR = new GlideRecord('sn_hr_core_bulk_case_request');
if (!bulkCaseRequestGR.get(bulkCaseRequestID))
throw this.getError("canCreateBulkCases' - 'Bulk case record' (" + bulkCaseRequestID + ") not found.");
var bulkCaseRequestStatus = bulkCaseRequestGR.getValue('status');
if (bulkCaseRequestStatus != 'requested')
return false;
//check if 'Bulk case user segments' are ready to process
return !this.isProcessingUserSegmentGroup(bulkCaseRequestID) && this.hasAtleastOneIncludedUserSegment(bulkCaseRequestID);
} catch (error) {
this.getError("'canCreateBulkCases': " + error);
}
},
/**
* Check if ALL `user-segment-groups` are processed
*
* @param {string} bulkCaseRequestID - sn_hr_core_bulk_case_request record sys_id
*
* @return {boolean}
*
* throws exception
*/
isProcessingUserSegmentGroup: function(bulkCaseRequestID) {
if (gs.nil(bulkCaseRequestID))
throw this.getError("isProcessingUserSegmentGroup' - missing sn_hr_core_bulk_case_request sys_id.");
var bcUserSegmentGroupGR = new GlideRecord('sn_hr_core_bulk_case_user_segment_group');
bcUserSegmentGroupGR.addQuery('bulk_case_request', bulkCaseRequestID);
bcUserSegmentGroupGR.addQuery('status', '!=', 'processed').addOrCondition('status', '');
bcUserSegmentGroupGR.setLimit(1);
bcUserSegmentGroupGR.query();
return bcUserSegmentGroupGR.hasNext();
},
/**
* Check if atleast one `user-segment` is in `included` state
*
* @param {string} bulkCaseRequestID - sn_hr_core_bulk_case_request record sys_id
*
* @return {boolean}
*
* throws exception
*/
hasAtleastOneIncludedUserSegment: function(bulkCaseRequestID) {
if (gs.nil(bulkCaseRequestID))
throw this.getError("hasAtleastOneIncludedUserSegment' - missing sn_hr_core_bulk_case_request sys_id.");
var bcUserSegmentGR = new GlideRecord('sn_hr_core_bulk_case_user_segment');
bcUserSegmentGR.addQuery('user_segment_group.bulk_case_request', bulkCaseRequestID);
bcUserSegmentGR.addQuery('user_segment_group.status', 'processed');
bcUserSegmentGR.addQuery('status', 'included');
bcUserSegmentGR.setLimit(1);
bcUserSegmentGR.query();
return bcUserSegmentGR.hasNext();
},
/**
* Method to count included user-records for bulk-case-request
*
* @param {string} bulkCaseRequestID - sn_hr_core_bulk_case_request record sys_id
*
* @return {Int} count
*
* throws exception
*/
getIncludedUserCount: function(bulkCaseRequestID) {
if (gs.nil(bulkCaseRequestID))
throw this.getError("getIncludedUserCount' - missing sn_hr_core_bulk_case_request sys_id.");
var bcUserSegmentGA = new GlideAggregate('sn_hr_core_bulk_case_user_segment');
bcUserSegmentGA.addNotNullQuery('user_segment_group_revision.sys_id');
bcUserSegmentGA.addQuery('user_segment_group_revision.bulk_case_request', bulkCaseRequestID);
bcUserSegmentGA.addQuery('user_segment_group_revision.status', 'processed');
bcUserSegmentGA.addQuery('status', 'included');
bcUserSegmentGA.addAggregate('COUNT');
bcUserSegmentGA.query();
bcUserSegmentGA.next();
return bcUserSegmentGA.getAggregate('COUNT');
},
/**
* Method to process 'Bulk case request' and create HR cases
*
* @param {GlideRecord} - sn_hr_core_case_request record
*
* throws exception
*/
createBulkCases: function(bulkCaseRequestGR) {
try {
if (!bulkCaseRequestGR.isValidRecord())
throw this.getError("'createBulkCases': Invalid 'Bulk case request' record.");
var bulkCaseRequestID = bulkCaseRequestGR.getUniqueValue();
if (!this.canCreateBulkCases(bulkCaseRequestID))
throw this.getError("'createBulkCases': Cannot create cases for 'Bulk case request' - ID: " + bulkCaseRequestID);
//mark 'Bulk case request' - `in_progress`
this.updateGlideRecord(bulkCaseRequestGR, {
'status': 'in_progress',
'start_time': new GlideDateTime()
});
//create parent case for bulk-case-request
var bulkRequestCaseID = '';
if (bulkCaseRequestGR.getValue('create_parent_case') == true) {
//set sys_created_by as subject_person and default hr_service for parent bulk-case
var userRecord = this.getUserRecordForName(bulkCaseRequestGR.getValue('sys_created_by'));
bulkRequestCaseID = this.createHRCase({
'subject_person': {
'value': userRecord.sys_id
},
'opened_for': {
'value': userRecord.sys_id
},
'bulk_case_request': {
'value': bulkCaseRequestID
},
'hr_service': {
'value': gs.getProperty('sn_hr_core.bulk_case_parent_service', 'c980f47c3b472200705d86a734efc449')
} //Alternatively use OOB HR service - 'Bulk Parent Case'
});
if (gs.nil(bulkRequestCaseID))
throw this.getError("'createBulkCases': Failed to create parent case for 'Bulk case request' - " + bulkCaseRequestID + ".");
}
//create HR case for all user-segments
var casesCreated = this.createHRCases(bulkCaseRequestGR, bulkRequestCaseID);
if (bulkRequestCaseID)
casesCreated++;
//log warning if less cases created for updated criteria on HR service (after processing user groups)
var casesToCreate = this.getIncludedUserCount(bulkCaseRequestID) + (bulkRequestCaseID? 1 : 0);
if (casesCreated < casesToCreate)
gs.warn("'"+ bulkCaseRequestGR.number +"': "+ casesCreated +" cases created as some user did not match the criteria on HR service.");
//update final count and mark 'Bulk case request' status - 'completed'
this.updateGlideRecord(bulkCaseRequestGR, {
'status': 'completed',
'cases_created_count': casesCreated,
'completed_time': new GlideDateTime()
});
} catch (error) {
this.updateGlideRecord(bulkCaseRequestGR, {
'status': 'error'
});
this.getError("'createBulkCases': " + error);
}
},
/**
* Method to create HR cases for sn_hr_core_bulk_case_user_segment
*
* @param {GlideRecord} bulkCaseRequestGR - sn_hr_core_case_request record
* @param {string} bulkRequestCaseID (optional) - sys_id of parent HR case created for 'Bulk case request'
*
* @return {int} number of HR cases created
*
* throws exception
*/
createHRCases: function(bulkCaseRequestGR, bulkRequestCaseID) {
if (!bulkCaseRequestGR.isValidRecord())
throw this.getError("'createHRCases': Invalid 'Bulk case request' record.");
var bulkCaseRequestID = bulkCaseRequestGR.getUniqueValue();
var bulkCaseHRServiceID = bulkCaseRequestGR.getValue('hr_service');
var casesCreated = 0;
//create HR cases for all user-segments marked 'included'
var userSegmentGR = new GlideRecord('sn_hr_core_bulk_case_user_segment');
userSegmentGR.addQuery('user_segment_group.bulk_case_request', bulkCaseRequestID);
userSegmentGR.addQuery('status', 'included');
userSegmentGR.query();
var curUserGroupRevisionIDs = {};
while (userSegmentGR.next()) {
//process user-segment only if it is the current revision of user-segment-group
if (this._hasCurUserGroupRevision(curUserGroupRevisionIDs, userSegmentGR)) {
//parse user-segment-data for HR case field values
var HRCaseData = userSegmentGR.user_segment_group_revision.case_data;
var fields = JSON.parse(HRCaseData);
//set parent for HR case
if (bulkRequestCaseID)
fields.parent = {
'value': bulkRequestCaseID
};
//set HR service
fields.hr_service = {
'value': bulkCaseHRServiceID
};
//set subject_person
var userSegmentValue = {
'value': userSegmentGR.getValue('user')
};
fields.subject_person = userSegmentValue;
//set user as opened-for if not explicitly set on user-segment-group
if (!fields.opened_for || !fields.opened_for.value)
fields.opened_for = userSegmentValue;
//set bulk_case_request
fields.bulk_case_request = {
'value': bulkCaseRequestID
};
//log failure to create case and continue
if (gs.nil(this.createHRCase(fields)))
this.getError("'createBulkCases': Failed to create HR case for user ID - " + userSegmentGR.user + ". For 'Bulk case request' ID - " + bulkCaseRequestID + ".");
else
casesCreated++;
//update 'Bulk case request' with progress
if ((casesCreated > 0) && (casesCreated % 100 == 0))
this.updateGlideRecord(bulkCaseRequestGR, {
'cases_created_count': casesCreated
});
}
}
return casesCreated;
},
/**
* Method to validate user-segment record for user-segment.group revision
*
* @params:
* {Object} stores {<user-segment-group>: <current revision>}
* {GlideRecord} sn_hr_core_bulk_case_user_segment record
*
* @returns {boolean}
* true if user-segment.group.revision matches user-segment.group_revision
* false otherwise
*
* NOTE:
* 'user-segment' references 'user-segment-group' via 'revision' as a reference-key
* After updating 'user-segment-group' new 'revision' is generated, and user-segment is never updated
* Thus discard user-segment with 'null' user-segment.user_segment_group_revision.sys_id. It is a 'invalid' user-segment.
*/
_hasCurUserGroupRevision: function(curUserGroupRevisionIDs, userSegmentGR) {
//user-segment is old and not valid
if (gs.nil(userSegmentGR.user_segment_group_revision.sys_id))
return false;
//compare cached current revision of user_segment.user_segment_group
else if (curUserGroupRevisionIDs.hasOwnProperty(userSegmentGR.user_segment_group))
return curUserGroupRevisionIDs[userSegmentGR.user_segment_group] == userSegmentGR.user_segment_group_revision;
//cache current valid revision for user-segment.user_segment_group
else if (userSegmentGR.user_segment_group.revision == userSegmentGR.user_segment_group_revision) {
curUserGroupRevisionIDs[userSegmentGR.user_segment_group] = userSegmentGR.user_segment_group.revision;
return true;
} else
return false;
},
/**
* Method to create HR case
*
* @param {Object} - Fields for HR case {'<field_name>': '<value>'}
*
* @return sys_id of the HR case created
*/
createHRCase: function(fields) {
var caseDetails = new sn_hr_core.hr_CaseCreation().createTask('sn_hr_core_case', fields, true);
if (!gs.nil(caseDetails) && caseDetails.hasOwnProperty('sys_id'))
return caseDetails.sys_id;
},
/**
* Method to update Glide Record
*
* @params
* glideRecord {GlideRecord} - record to update
* fields {Object} - {'<field_name>': '<value>'}
*
* throws exception
*/
updateGlideRecord: function(glideRecord, fields) {
if (!glideRecord.isValidRecord())
throw this.getError("'updateGlideRecord': Invalid Glide Record.");
if (gs.nil(fields))
throw this.getError("'updateGlideRecord': No field to update record.");
//set field values
for (var field in fields)
glideRecord.setValue(field, fields[field]);
//update 'Bulk case request'
if (!glideRecord.update(gs.getMessage("Updated by 'hr_BulkCaseRequestUtils().updateGlideRecord()'.")))
this.getError("'updateGlideRecord' - Failed to update Glide Record (" + bulkCaseRequestGR.getUniqueID() + ").");
},
/**
* Method to fetch sys_user record
*
* @param {string} userName
*
* @return {GlideRecord} sys_user record
*/
getUserRecordForName: function(userName) {
var userRecord = new GlideRecord('sys_user');
userRecord.addQuery('user_name', userName);
userRecord.setLimit(1);
userRecord.query();
userRecord.next();
return userRecord;
},
/**
* Method to be used when throwing an exception. To get an error object from the message. This method logs the
* message and returns an Error object.
*
* @param {string} message - The error message.
*
* @return {Error} - The error object.
*/
getError: function(message) {
var errorMessage = 'Script include: hr_BulkCaseRequestUtils - ' + message;
gs.error(errorMessage);
return new Error(errorMessage);
},
type: 'hr_BulkCaseRequestUtils'
};
Sys ID
17d2993d0fc32010af170c3635767ecf