Name
sn_hr_core.hr_CaseCreation
Description
No description available
Script
var hr_CaseCreation = Class.create();
hr_CaseCreation.prototype = {
initialize: function() {
this.TEXT_QUERY = "123TEXTQUERY321";
this.sysUserTable = "sys_user";
this.searchTables = ["sys_user", "sn_hr_core_profile"]; // TODO Better support extended tables (eg. u_employee extending sys_user)
this.priorityTable = null;
this.priorityColumn = null;
this.LEFT_TASK_FIELDS = "fields_left_task";
this.RIGHT_TASK_FIELDS = "fields_right_task";
this.CASE_CREATION_SERVICE_CONFIG_SYSID = ["f7ec702beb520300a9e7e26ac106fe56", "a1e6e28bff26201017e447cf793bf11c", "4e3ee81a23030010fb0c949e27bf65a0"];
// Create configuration object based on configuration record
var evConfigGr = new GlideRecord("sn_hr_core_config_case_creation");
evConfigGr.setLimit(1);
evConfigGr.query();
if (evConfigGr.next()) {
// Search attributes
this.pageSize = parseInt(evConfigGr.getValue("page_size"));
this.minimumInputLength = parseInt(evConfigGr.getValue("minimum_input_length")) || 2;
this.forcePartialSearch = evConfigGr.getValue("force_partial_search") == "1";
this.allowSkippingVerification = evConfigGr.getValue("allow_skipping_verification") == "1";
// Employee Search
this.userObjectTable = evConfigGr.getValue("display_table");
this.userSearchCondition = (evConfigGr.getValue("limit_users_on_search") == "1") ? evConfigGr.getValue("user_search_condition") : "";
this.userColumn = evConfigGr.getValue("user_field");
this.additionalDisplayFields = evConfigGr.getValue("additional_display_fields") ? evConfigGr.getValue("additional_display_fields").split(",") : [];
this.links = evConfigGr.getValue("links") ? evConfigGr.getValue("links").split(",") : [];
if(evConfigGr.getValue("search_tables")){
this.searchTables = evConfigGr.getValue("search_tables").split(",");
this.priorityTable = evConfigGr.getValue('priority_table_name');
this.priorityColumn = evConfigGr.getValue('priority_column');
}
// Case search
this.taskSearchTable = evConfigGr.getValue("task_search_table");
this.taskSearchCondition = (evConfigGr.getValue("limit_tasks_on_search") == "1") ? evConfigGr.getValue("task_search_condition") : "";
this.taskUserFields = evConfigGr.getValue("task_user_fields") ? evConfigGr.getValue("task_user_fields").split(",") : [];
// Employee information
this.fields = {
left_fields : evConfigGr.getValue("fields_left") ? evConfigGr.getValue("fields_left").split(",") : [],
right_fields : evConfigGr.getValue("fields_right") ? evConfigGr.getValue("fields_right").split(",") : []
};
// Case creation
this.taskCreateTable = evConfigGr.getValue("task_create_table");
this.serviceCondition = (evConfigGr.getValue("limit_services") == "1") ? evConfigGr.getValue("service_condition") : "";
this.fieldsMinimumInputLength = parseInt(evConfigGr.getValue("fields_minimum_input_length")) || 0;
this.taskFields = {
left_fields : evConfigGr.getValue("fields_left_task") ? evConfigGr.getValue("fields_left_task").split(",") : [],
right_fields : evConfigGr.getValue("fields_right_task") ? evConfigGr.getValue("fields_right_task").split(",") : [],
bottom_fields : evConfigGr.getValue("fields_bottom_task") ? evConfigGr.getValue("fields_bottom_task").split(",") : []
};
} else { // Default if record not found
// Search attributes
this.pageSize = 10;
this.minimumInputLength = 4;
this.forcePartialSearch = true;
this.allowSkippingVerification = true;
// Employee Search
this.userObjectTable = "sn_hr_core_profile";
this.userSearchCondition = "";
this.userColumn = "user";
this.additionalDisplayFields = ["user.department", "user.employee_number", "user.location"];
this.links = [];
// Case search
this.taskSearchTable = "sn_hr_core_case";
this.taskSearchCondition = "";
this.taskUserFields = ["subject_person", "opened_for", "opened_by", "watch_list"];
// Employee information
this.fields = {
left_fields : ["user.name", "user.employee_number"],
right_fields : ["user.email", "user.zip"]
};
// Case creation
this.taskCreateTable = "sn_hr_core_case";
this.serviceCondition = "";
this.fieldsMinimumInputLength = 0;
this.taskFields = {
left_fields : ["opened_for"],
right_fields : ["subject_person"],
bottom_fields : ["work_notes"]
};
}
this.taskPrefixes = [];
var sysNumberGr = new GlideRecord("sys_number");
sysNumberGr.addQuery("category", "INSTANCEOF", this.taskSearchTable);
sysNumberGr.query();
while (sysNumberGr.next())
this.taskPrefixes.push(sysNumberGr.getValue("prefix"));
},
/**
* Search for an employee by key words
* @param searchTermParam String Search term input
* @param searchPage number Search page used for pagination (starts at 0)
* @param searchTable String (optional) Table name used for pagination
* @return Object
* Example:
* {
* list : Array
* Either an array of Objects from @function getUserObject and irQueryScore for table searches OR
* Objects for task searches, Example:
* {
* display : String Task display value,
* users : array of Objects from @function getUserObject,
* irQueryScore: integer representing search relevance (high score represents more relevance)
* }
* total : number The total number of search results (can be more than results returned),
* table : String Table name to use for pagination
* }
*/
search: function(searchTermParam, searchPage, searchTable) {
var list = [];
var total = 0;
var table = "";
var MAX_QUERY_SCORE = 999;
// Parse search terms
var taskTerms = [];
var searchTerms = [];
// Example: ^(HRC|HRT)[0-9]+$
var taskRegex = "^(" + this.taskPrefixes.join("|") + ")[0-9]+$";
var searchTermParams = searchTermParam.split(" ");
for (var i = 0; i < searchTermParams.length; i++)
if (searchTermParams[i].match(taskRegex, "i"))
taskTerms.push(searchTermParams[i]);
else if (searchTermParams[i])
searchTerms.push(this.appendPartialSearch(searchTermParams[i]));
var taskTerm = taskTerms.join(" | ");
var searchTerm = searchTerms.join(" ");
// TODO This prevents searching users if task term is found, but what if user meant to search users?
// Search tasks only if we have task search terms
if (taskTerm) {
var userTables = new GlideTableHierarchy("sys_user").getAllExtensions();
var userObjectTables = new GlideTableHierarchy(this.userObjectTable).getAllExtensions();
// Search for relevant tasks
var taskSearchGr = new GlideRecord(this.taskSearchTable);
taskSearchGr.addQuery(this.TEXT_QUERY, taskTerm);
if (searchTerm)
taskSearchGr.addQuery(this.TEXT_QUERY, searchTerm);
if (this.taskSearchCondition)
taskSearchGr.addEncodedQuery(this.taskSearchCondition);
taskSearchGr.chooseWindow(searchPage * this.pageSize, (searchPage * this.pageSize) + this.pageSize);
taskSearchGr.orderBy("ir_query_score");
taskSearchGr.query();
while (taskSearchGr.next()) {
if (!taskSearchGr.canRead())
continue;
var taskObject = {
displayValue: taskSearchGr.getDisplayValue(),
table: taskSearchGr.getRecordClassName(),
reference: taskSearchGr.getRecordClassName(),
value: taskSearchGr.getUniqueValue(),
label: taskSearchGr.getClassDisplayValue(),
column_name: "task_object",
internal_type: "reference",
type: "reference",
tooltip: gs.getMessage("Preview record for field: {0}", taskSearchGr.getClassDisplayValue())
};
// Find all relevant users on a given task
var taskUserList = [];
var taskUserMap = {};
for (var j = 0; j < this.taskUserFields.length; j++) {
var element = taskSearchGr.getElement(this.taskUserFields[j]);
if (element == null || element.toString() == null || !element.canRead())
continue;
var eleEd = element.getED();
var eleInternalType = eleEd.getInternalType();
if (eleInternalType == "reference" || eleInternalType == "glide_list") {
var eleTable = eleEd.getReference();
// Verify eleTable is a sys_user or extension, or a this.userObjectTable or extension
if (!eleTable || (userTables.indexOf(eleTable) == -1 && userObjectTables.indexOf(eleTable) == -1))
continue;
var elementTableGr = new GlideRecordSecure(eleTable);
elementTableGr.addQuery("sys_id", "IN", element.toString());
if (searchTerm)
elementTableGr.addQuery(this.TEXT_QUERY, searchTerm);
elementTableGr.setLimit(100); // Limit results just in case
elementTableGr.orderBy(elementTableGr.getDisplayName());
elementTableGr.query();
while (elementTableGr.next()) {
// Skip this record if it was already added (doesn't work for non sys_user references)
if (taskUserMap.hasOwnProperty(elementTableGr.getUniqueValue())) {
taskUserMap[elementTableGr.getUniqueValue()].display_suffix.push(element.getLabel());
continue;
}
var userElementObject = this.getUserObject(elementTableGr);
if (userElementObject) {
// This second check is needed if the element does not reference sys_user
if (taskUserMap.hasOwnProperty(userElementObject.sys_id)) {
taskUserMap[userElementObject.sys_id].display_suffix.push(element.getLabel());
continue;
}
userElementObject.display_suffix = [element.getLabel()];
userElementObject.task = taskObject;
taskUserMap[userElementObject.sys_id] = userElementObject;
taskUserList.push(userElementObject);
}
}
}
}
if (taskUserList.length > 0) {
list.push({
display: taskSearchGr.getDisplayValue(),
users: taskUserList,
irQueryScore: taskSearchGr.getValue('ir_query_score')
});
}
}
table = this.taskSearchTable;
total = taskSearchGr.getRowCount();
// Search user tables
// Search this.searchTables, only returning results from one table failing over to the next when no results are found
} else {
// Skip to requested table if provided
var k = 0;
if (searchTable)
k = this.searchTables.indexOf(searchTable);
var priorityTotal = 0;
var remainingCount = 0;
var startOffset = 0;
var endOffset = 0;
var remainder = 0;
var fieldName = this.priorityColumn;
var forcePartialSearchWithPriority = (this.priorityColumn != null) && this.forcePartialSearch;
var forcePartialSearchWithoutPriority = (this.priorityColumn == null) && this.forcePartialSearch;
// If priority table is used. Move priority table to the first position in search tables
if(forcePartialSearchWithPriority) {
for(var idx = 0; idx < this.searchTables.length; idx++){
if(this.searchTables[idx] == this.priorityTable){
var priorityTable = this.searchTables.splice(idx,1);
this.searchTables.unshift(priorityTable[0]);
}
}
}
for (/* k is instantiated above */; k > -1 && k < this.searchTables.length && list.length == 0 && total == 0 && (!searchTable || searchTable == this.searchTables[k]); k++) {
var columnName = this.priorityColumn;
if (forcePartialSearchWithPriority && this.searchTables[k] == this.priorityTable) {
var priorityColumnGr = new GlideRecordSecure(this.searchTables[k]);
var encodedQueryString = columnName + "STARTSWITH" + searchTermParam;
priorityColumnGr.addEncodedQuery(encodedQueryString);
if (this.userSearchCondition)
priorityColumnGr.addEncodedQuery(this.getUserQuery(this.userSearchCondition, this.searchTables[k]));
priorityColumnGr.chooseWindow(searchPage * this.pageSize, (searchPage * this.pageSize) + this.pageSize);
priorityColumnGr.query();
priorityTotal = priorityColumnGr.getRowCount();
while (priorityColumnGr.next()) {
var userObject = this.getUserObject(priorityColumnGr);
userObject.irQueryScore = MAX_QUERY_SCORE;
if (userObject && userObject.display)
list.push(userObject);
}
if (list.length < this.pageSize)
remainingCount = this.pageSize - list.length;
}
if (priorityTotal > 0 && this.searchTables[k] == this.priorityTable) { // prioirty search has results
remainder = priorityTotal % this.pageSize;
startOffset = Math.floor((priorityTotal-remainder)/this.pageSize) * this.pageSize;
endOffset = startOffset;
if (list.length == 0) // prioirty search results are exhausted
startOffset += remainder;
}
// Zing search should be performed when:
// ForcePartialSearch is false OR
// Results from priority search are NOT enough for a page OR
// ForcePartialSearch selected with None option
if (remainingCount > 0 || ! this.forcePartialSearch || forcePartialSearchWithoutPriority) {
// Search table using search input as key word search
var searchGr = new GlideRecordSecure(this.searchTables[k]);
searchGr.addQuery(this.TEXT_QUERY, searchTerm);
if (forcePartialSearchWithPriority && this.searchTables[k] == this.priorityTable)
searchGr.addQuery(columnName, 'NOT LIKE', searchTermParam+"%");
if (this.userSearchCondition)
searchGr.addEncodedQuery(this.getUserQuery(this.userSearchCondition, this.searchTables[k]));
var window = {
"start": searchPage * this.pageSize - startOffset,
"end": (searchPage * this.pageSize) + this.pageSize - remainder - endOffset
};
searchGr.chooseWindow(window.start, window.end);
searchGr.orderBy("ir_query_score");
searchGr.query();
total = searchGr.getRowCount();
table = this.searchTables[k];
while (searchGr.next()) {
var userObject = this.getUserObject(searchGr);
userObject.irQueryScore = searchGr.getValue('ir_query_score');
if (userObject && userObject.display)
list.push(userObject);
}
} else { // Total calculation for pagination.
var searchGr = new GlideRecordSecure(this.searchTables[k]);
searchGr.addQuery(this.TEXT_QUERY, searchTerm);
if (forcePartialSearchWithPriority && this.searchTables[k] == this.priorityTable)
searchGr.addQuery(columnName, 'NOT LIKE', searchTermParam+"%");
if (this.userSearchCondition)
searchGr.addEncodedQuery(this.getUserQuery(this.userSearchCondition, this.searchTables[k]));
searchGr.query();
total = searchGr.getRowCount();
}
// If search table is provided, don't failover to next table
if (searchTable)
break;
}
}
return {
list: list,
total: total + priorityTotal,
table: table
};
},
//Remove fields user cannot write to
removeFieldsUserCannotWrite: function(tableGr, taskFields) {
for (var keyList in taskFields)
for (var k = taskFields[keyList].length - 1; k > -1; k--) {
var ele = tableGr.getElement(taskFields[keyList][k].column_name);
if (ele == null || !ele.canRead() || !ele.canCreate()) // canCreate controls write access for new records
taskFields[keyList].splice(k, 1);
}
},
/**
* Force a search term to allow partial matching
* @param searchTerm String Search term to force partial searching on
* @return String Partialized search term
*/
appendPartialSearch: function(searchTerm) {
if (this.forcePartialSearch
&& searchTerm.indexOf("*") == -1
&& searchTerm.indexOf('"') == -1
&& searchTerm.indexOf("'") != 0 // Not the first character
&& searchTerm.indexOf("'") != (searchTerm.length - 1) // Not the last character
&& searchTerm != "AND"
&& searchTerm != "OR"
&& searchTerm != "|")
return searchTerm += "*";
return searchTerm;
},
/**
* Adapt an encoded query to work when querying this.userObjectTable instead of sys_user table
* Example: For @param encodedQuery of "active=true^ORmarital_status=single"
* return "user.active=true^ORuser.marital_status=single" for sn_hr_core_profile
* return "active=true^ORmarital_status=single" for sys_user
* @param encodedQuery String Field name to parse
* @param tableName String table name to query on
* @return String Parsed encoded query
*/
getUserQuery: function(encodedQuery, tableName) {
if (!encodedQuery || tableName != this.userObjectTable || !this.userColumn)
return encodedQuery;
if (encodedQuery.endsWith("^EQ"))
encodedQuery = encodedQuery.substring(0, encodedQuery.length - 3);
var queries = encodedQuery.split("^NQ");
var queriesRet = [];
for (var i = 0; i < queries.length; i++) {
var orConditions = queries[i].split("^OR");
var orConditionsRet = [];
for (var j = 0; j < orConditions.length; j++) {
var andConditions = orConditions[j].split("^");
var andConditionsRet = [];
for (var k = 0; k < andConditions.length; k++)
andConditionsRet.push(this.userColumn + "." + andConditions[k]);
if (andConditionsRet.length > 0)
orConditionsRet.push(andConditionsRet.join("^"));
}
if (orConditionsRet.length > 0)
queriesRet.push(orConditionsRet.join("^OR"));
}
return queriesRet.join("^NQ");
},
/**
* Return a user object for a given GlideRecord
* @param record GlideRecord to use as basis for user object
* @return Object
* Example:
* {
* sys_id : sys_id of a user,
* display : display value of a user,
* table: reference table of user field, or table of the user record,
* has_ev_record: boolean representing if Employee Verification record exists,
* ev_sys_id : sys_id of employee verification record,
* ev_table : table of the employee verification record,
* tooltip : display value for tooltip on reference icon,
* active: boolean if user is active,
* additional_display_fields : (optional) array of field display values,
* left_fields : (optional) array from @function getFieldObjects,
* right_fields : (optional) array from @function getFieldObjects
* }
*/
getUserObject: function(record) {
// Attempt to find the evConfig table's record for the passed in record
var hasEVRecord = false; // Failover if not found to parsing out the user fields on evconfig
var recordTable = record.getTableName();
if (recordTable != this.userObjectTable) {
var userObjectTableGr = new GlideRecord(this.userObjectTable);
if (this.userColumn && userObjectTableGr.isValidField(this.userColumn) && userObjectTableGr.get(this.userColumn, record.getUniqueValue())) {
record = userObjectTableGr;
hasEVRecord = true;
}
} else
hasEVRecord = true;
var userObject = {
sys_id: (hasEVRecord && this.userColumn) ? record.getValue(this.userColumn) : record.getUniqueValue(),
display: (hasEVRecord && this.userColumn) ? record.getElement(this.userColumn).getDisplayValue() : record.getDisplayValue(),
table: (hasEVRecord && this.userColumn && record.getElement(this.userColumn).getED().getInternalType() == "reference") ? record.getElement(this.userColumn).getReferenceTable() : record.getTableName(),
has_ev_record: hasEVRecord,
ev_sys_id: (hasEVRecord) ? record.getUniqueValue() : '',
ev_table: (hasEVRecord) ? record.getTableName() : '',
tooltip: gs.getMessage("Preview record for field: {0}", (hasEVRecord && this.userColumn && record.getElement(this.userColumn) != null) ? record.getElement(this.userColumn).getLabel() : record.getClassDisplayValue())
};
if (this.links.length && userObject.ev_sys_id && userObject.ev_table) {
userObject.links = [];
for (var j = 0; j < this.links.length; j++) {
var linkGr = new GlideRecord("link_generator_mapping");
if (linkGr.get(this.links[j]))
userObject.links.push({url:'', btnName:linkGr.getDisplayValue('btn_name')});
}
}
// Add "active" property
var userPrefix = (hasEVRecord && this.userColumn) ? (this.userColumn + ".") : "";
var activeElement = record.getElement(userPrefix + "active");
if (activeElement != null && activeElement.toString() != null && activeElement.toString() !== "true")
userObject.active = activeElement.toString() === "true";
// Add display values for additional display fields
if (this.additionalDisplayFields && this.additionalDisplayFields.length) {
var additionalDisplayFieldsArr = [];
for (var i = 0; i < this.additionalDisplayFields.length; i++) {
var fieldName = this.getUserField(this.additionalDisplayFields[i], hasEVRecord);
var fieldElement = record.getElement(fieldName);
if (fieldElement != null && fieldElement.toString() !== null && fieldElement.canRead())
additionalDisplayFieldsArr.push(fieldElement.getDisplayValue());
}
if (additionalDisplayFieldsArr.length)
userObject.additional_display_fields = additionalDisplayFieldsArr;
}
this._fillWorkspaceUserFields(record, userPrefix, userObject);
// Add all field lists to userObject
for (var key in this.fields)
// Skip mandatory check on EV fields for performance
userObject[key] = this.getFieldObjects(record, this.fields[key], hasEVRecord, null, true);
return userObject;
},
_fillWorkspaceUserFields: function(record, userPrefix, userObject) {
var workspaceUserFields = ['avatar', 'vip', 'active'];
var workspaceUserValues = {};
for (var i = 0; i < workspaceUserFields.length; i++) {
var fieldName = userPrefix + workspaceUserFields[i];
var fieldElement = record.getElement(fieldName);
if (fieldElement !== null && fieldElement.toString() !== null && fieldElement.canRead())
workspaceUserValues[workspaceUserFields[i]] = fieldElement.getDisplayValue();
}
userObject.workspaceUserValues = workspaceUserValues;
},
/**
* Parse a field name to retrieve a dot walked column when a user does not have a record in the specified EV Config table
* Example: For @param fieldName of "user.employee_number", parse out "employee_number"
* @param fieldName String Field name to parse
* @param hasEVRecord (optional) boolean Employee Verification record exists
* @return String Parsed field name
*/
getUserField: function(fieldName, hasEVRecord) {
if (hasEVRecord || !fieldName)
return fieldName;
if (fieldName.startsWith(this.userColumn + "."))
return fieldName.slice(this.userColumn.length + 1); // Attempt to directly grab the user field
return null;
},
/**
* Call @function getFieldObject on an array of field names
* @param record GlideRecord to use in @function getFieldObject
* @param fieldList array Array of field names to use in @function getFieldObject
* @param hasEVRecord boolean Employee Verification record exists for record
* @param fieldValues - Object - (optional) Object of field-value pairs for the @param record
* @param skipMandatoryCheck boolean Skip mandatory check on fields
* @return array of field objects produced from @function getFieldObject
*/
getFieldObjects: function(record, fieldList, hasEVRecord, fieldValues, skipMandatoryCheck) {
// Default field values for non-existent record; attempt to reduce skipping of task numbers
if (record && record.isValid() && !record.isValidRecord() && !record.getElement("number").toString()) {
record.newRecord();
this.setInitialCaseFields(record);
// Setting fields for _isFieldMandatory function
if (fieldValues)
for (var key in fieldValues) {
if (fieldValues[key] != null && record.isValidField(key))
record.setValue(key, fieldValues[key]);
}
}
//Table hierarchy for field's mandatory check
var tableHierarchy = new GlideTableHierarchy(record.getRecordClassName()).getTables();
var fields = [];
for (var i = 0; i < fieldList.length; i++) {
var field = this.getFieldObject(record, this.getUserField(fieldList[i], hasEVRecord), tableHierarchy, skipMandatoryCheck);
if (field)
fields.push(field);
}
return fields;
},
/**
* Return a field object for a given GlideRecord and field name
* @param record GlideRecord to create field object from
* @param fieldName String Field name to create a field object for
* @param tableHierarchy Array list of table hierarchy
* @param skipMandatoryCheck boolean Skip mandatory check on field
* Example:
* @return Object
* {
* display : display value of a field,
* label : label of a field,
* value : value of a field,
* column_name : column name of a field,
* max_length : max length of a field,
* internal_type : internal type of a field,
* type : internal type of a field (used for DEO angular directive)
* referringRecordId : sys_id of record from where field object is created
* }
*/
getFieldObject: function(record, fieldName, tableHierarchy, skipMandatoryCheck) {
var element = record.getElement(fieldName);
if (element == null || element.toString() == null || !element.canRead())
return null;
var eleEd = element.getED();
//verify table hierarchy is set
if (!tableHierarchy)
tableHierarchy = new GlideTableHierarchy(record.getRecordClassName()).getTables();
var fieldObject = {
display: element.getDisplayValue(),
label: element.getLabel(),
value: element.toString(),
column_name: fieldName,
max_length: eleEd.getLength(),
minimumInputLength: this.fieldsMinimumInputLength,
internal_type: eleEd.getInternalType(),
type: eleEd.getInternalType(),
hint: eleEd.getHint(),
mandatory: skipMandatoryCheck ? false : this.isFieldMandatory(record, fieldName, tableHierarchy),
referringRecordId: record.getUniqueValue(),
referringTable: record.getTableName()
};
if (eleEd.getInternalType() == "reference")
this._addReferenceProperties(fieldObject, element, record.getTableName());
else if (eleEd.getInternalType() == "glide_list")
this._addGlideListProperties(fieldObject, element, record.getTableName());
else if (["currency", "price"].indexOf(eleEd.getInternalType()) > -1)
this._addCurrencyProperties(fieldObject, element, record.getTableName());
else if (eleEd.isChoiceTable())
this._addChoiceProperties(fieldObject, element, record.getTableName());
return fieldObject;
},
/**
* @Returns boolean:
* true if field is set mandatory by,
* 1. Table schema
* 2. Dictionary override
* 3. Data Policy
* 4. UI Policy
* false otherwise
*
* NOTE: Client scripts and scripted UI policies are ignored
*
* @Params:
* record: Gliderecord where the field is defined
* fieldName: String value of field name
* tableHierarchy: Array list of table hierarchy
**/
isFieldMandatory: function(record, fieldName, tableHierarchy) {
// Check table schema
var gr = new GlideRecord('sys_dictionary');
gr.addQuery('name', 'IN', tableHierarchy);
gr.addQuery('element', fieldName);
gr.addQuery('mandatory', true);
gr.query();
if (gr.next())
return true;
//Check dictionary overrides
if (this._isFieldSetMandatoryByDictionaryOverride(record, fieldName, tableHierarchy))
return true;
// Check Data Policies
if (this._isFieldSetMandatoryByDataPolicy(record, fieldName, tableHierarchy))
return true;
// Check UI Policies
if (this._isFieldSetMandatoryByUIPolicy(record, fieldName, tableHierarchy))
return true;
return false;
},
/**
* @Returns boolean:
* true if field is set mandatory using dictionary override
* false otherwise
*
* @Params:
* fieldName: String value of field name
* tableHierarchy: Array list of table hierarchy
**/
_isFieldSetMandatoryByDictionaryOverride: function(record, fieldName, tableHierarchy) {
var isMandatorySetForRecordTable = false;
var mandatorySetOnRecordTable = false;
var mandatorySetOnTableHierarchy = false;
var gr = new GlideRecord('sys_dictionary_override');
gr.addQuery('name', 'IN', tableHierarchy);
gr.addQuery('element', fieldName);
gr.addQuery('mandatory_override', true);
gr.query();
while(gr.next()) {
var mandatory = gr.mandatory.toString();
//use field mandatory override set on record table
if (gr.name.toString() == record.getRecordClassName()) {
isMandatorySetForRecordTable = true;
mandatorySetOnRecordTable = (mandatory == 'true');
}
//OR use mandatory override set on table hierarchy
else if (mandatory == 'true')
mandatorySetOnTableHierarchy = true;
}
return isMandatorySetForRecordTable ? mandatorySetOnRecordTable : mandatorySetOnTableHierarchy;
},
/**
* @Returns boolean:
* true if field is set mandatory using data policy
* false otherwise
*
* @Params:
* record: Gliderecord where the field is defined
* fieldName: String value of field name
* tableHierarchy: Array list of table hierarchy
**/
_isFieldSetMandatoryByDataPolicy: function(record, fieldName, tableHierarchy) {
var dataPolicies = {};
var recordTable = record.getRecordClassName();
var gr = new GlideRecord('sys_data_policy_rule');
gr.addQuery('table', 'IN', tableHierarchy);
gr.addQuery('sys_data_policy.active', 'true');
gr.addQuery('field', fieldName);
gr.addQuery('mandatory', '!=', 'ignore');
gr.query();
while (gr.next()){
var table = gr.table.toString();
var inheritPolicy = (gr.sys_data_policy.inherit.toString() == 'true');
var reverseIfFalse = (gr.sys_data_policy.reverse_if_false.toString() == 'true');
var conditions = gr.sys_data_policy.conditions.toString();
var mandatory = (gr.mandatory.toString() == 'true');
//data policy for the table
if (table == recordTable)
dataPolicies[table] = this._validatePolicyCondition(mandatory, record, conditions, reverseIfFalse);
//inherited data policies
else if (inheritPolicy)
dataPolicies[table] = this._validatePolicyCondition(mandatory, record, conditions, reverseIfFalse);
}
return this._mandatorySetByDataPolicy(dataPolicies, recordTable);
},
_mandatorySetByDataPolicy : function(dataPolicies, curTable) {
var baseTable = new GlideTableHierarchy(curTable).getBase();
if (typeof dataPolicies[curTable] !== 'undefined')
return dataPolicies[curTable];
else if (curTable != baseTable)
return this._mandatorySetByDataPolicy(dataPolicies, baseTable);
else
return false;
},
_validatePolicyCondition: function(mandatory, record, conditions, reverseIfFalse) {
var policyConditionMatched = ScopedGlideFilter.checkRecord(record, conditions);
if (policyConditionMatched)
return mandatory;
else
return (reverseIfFalse && !mandatory);
},
/**
* @Returns boolean:
* true if field is set mandatory using UI policy
* false otherwise
*
* NOTE: UI policies are evaluated in an ascending order
*
* @Params:
* record: Gliderecord where the field is defined
* fieldName: String value of field name
* tableHierarchy: Array list of table hierarchy
**/
_isFieldSetMandatoryByUIPolicy: function(record, fieldName, tableHierarchy) {
var recordTable = record.getRecordClassName();
var gr = new GlideRecord('sys_ui_policy_action');
gr.addQuery('table', 'IN', tableHierarchy);
gr.addQuery('ui_policy.active', 'true');
gr.addQuery('ui_policy.global', 'true');
gr.addQuery('field', fieldName);
gr.addQuery('mandatory', '!=', 'ignore');
gr.orderByDesc('ui_policy.order');
gr.query();
while (gr.next()){
var isRecordTable = (gr.table.toString() == recordTable);
var inheritPolicy = (gr.ui_policy.inherit.toString() == 'true');
if (isRecordTable || inheritPolicy) {
var reverseIfFalse = (gr.ui_policy.reverse_if_false.toString() == 'true');
var conditions = gr.ui_policy.conditions.toString();
var mandatory = (gr.mandatory.toString() == 'true');
return this._validatePolicyCondition(mandatory, record, conditions, reverseIfFalse);
}
}
return false;
},
/**
* Add reference specific properties to a given Object from @function getFieldObject
* @param fieldObject Object Field object from @function getFieldObject
* @param element GlideElement Field element
* @param tableName String Table name to get qualifier for
* Adds properties:
* reference : table name for a reference field,
* qualifier : reference qualifier for a reference field,
* displayValue : display value for a reference field,
* refTable : string value of table name where field is,
* tooltip : display value for tooltip on reference icon,
* external_space_id : (optional) space id used for showing floor plan,
* external_level_id : (optional) level id used for showing floor plan,
* external_building_id : (optional) building id used for showing floor plan,
* campus_sys_id : (optional) campus sys_id used for showing floor plan
*/
_addReferenceProperties: function(fieldObject, element, tableName) {
fieldObject.reference = element.getReferenceTable();
var qualifier = element.getED().getReferenceQualifier();
if (qualifier && !qualifier.startsWith("javascript:"))
fieldObject.qualifier = qualifier;
fieldObject.displayValue = element.getDisplayValue();
fieldObject.refTable = element.getTableName();
fieldObject.refId = -1;
var eleRecord = new GlideRecord(fieldObject.reference);
if (!eleRecord.isValid())
return;
fieldObject.searchField = eleRecord.getDisplayName();
fieldObject.tooltip = gs.getMessage("Preview record for field: {0}", element.getLabel());
// Floor Plan specific properties
if (element.external_space_id) {
fieldObject.external_space_id = element.external_space_id.toString();
fieldObject.external_level_id = element.floor.external_level_id.toString();
fieldObject.external_building_id = element.building.external_building_id.toString();
fieldObject.campus_sys_id = element.building.campus.toString();
}
},
/**
* Add glide_list specific properties to a given Object from @function getFieldObject
* @param fieldObject Object Field object from @function getFieldObject
* @param element GlideElement Field element
* @param tableName String Table name to get qualifier for
* Adds properties:
* reference : table name for a glide_list field,
* qualifier : reference qualifier for a glide_list field,
* displayValue : display value for a glide_list field,
* display : display for a glide_list field,
* tooltip : display value for tooltip on reference icon,
* selectedOptions : Array of glide_list choice objects,
* Example:
* [{
* value: choice value,
* label: choice label
* }]
*/
_addGlideListProperties: function(fieldObject, element, tableName) {
var eleEd = element.getED();
fieldObject.reference = eleEd.getReference();
var qualifier = eleEd.getReferenceQualifier();
if (qualifier && !qualifier.startsWith("javascript:"))
fieldObject.qualifier = qualifier;
fieldObject.displayValue = "";
fieldObject.display = "";
fieldObject.selectedOptions = [];
var eleRecord = new GlideRecord(fieldObject.reference);
if (!eleRecord.isValid())
return;
fieldObject.searchField = eleRecord.getDisplayName();
fieldObject.tooltip = gs.getMessage("Preview record for field: {0}", element.getLabel());
var values = fieldObject.value.split(",");
for (var i = 0; i < values.length; i++)
if (eleRecord.get(values[i])) {
fieldObject.selectedOptions.push({
value : eleRecord.getUniqueValue(),
label : eleRecord.getDisplayValue()
});
}
fieldObject.value = fieldObject.value.length > 0 ? fieldObject.value : '';
},
/**
* Add currency specific properties to a given Object from @function getFieldObject
* @param fieldObject Object Field object from @function getFieldObject
* @param element GlideElement Field element
* @param tableName String Table name to get qualifier for
* Adds properties:
* currencyCodes : Array of currency code objects,
* Example:
* [{
* code: String currency code (e.g. USD),
* symbol: String currency symbol (e.g. $)
* }]
* currencyCode : String currency code (e.g. USD),
* currencyValue : String currency value (e.g. 123.69)
*/
_addCurrencyProperties: function(fieldObject, element, tableName) {
// Get properties for single currency mode
if (!this.hasOwnProperty("i18n_single_currency")) {
this.i18n_single_currency = gs.getProperty("glide.i18n.single_currency") === "true";
if (this.i18n_single_currency)
this.i18n_single_currency_code = gs.getProperty("glide.i18n.single_currency.code");
}
fieldObject.currencyCodes = [];
var currenciesGr = new GlideRecord("fx_currency");
if (this.i18n_single_currency)
currenciesGr.addQuery("code", this.i18n_single_currency_code);
else {
currenciesGr.addActiveQuery();
currenciesGr.orderBy("symbol");
}
currenciesGr.query();
while (currenciesGr.next())
fieldObject.currencyCodes.push({ code : currenciesGr.getValue("code"), symbol : currenciesGr.getValue("symbol") });
// Get the session code and value when single currency or no value set, otherwise get the set values
if (this.i18n_single_currency || element.toString() == "0" || !element.toString()) {
fieldObject.currencyCode = element.getSessionCurrencyCode();
fieldObject.currencyValue = element.getSessionValue();
} else {
fieldObject.currencyCode = element.getCurrencyCode();
fieldObject.currencyValue = element.getCurrencyValue();
}
// Add the user's currency code to the currency list if it is not there already
for (var i = 0; i < fieldObject.currencyCodes.length; i++)
if (fieldObject.currencyCodes[i].code === fieldObject.currencyCode)
return;
fieldObject.currencyCodes.push({ code : fieldObject.currencyCode, symbol: fieldObject.currencyCode });
},
/**
* Add choice specific properties to a given Object from @function getFieldObject
* @param fieldObject Object Field object from @function getFieldObject
* @param element GlideElement Field element to get choices for
* @param tableName String Table name to get choices from
* Adds property:
* choiceList : Array of choice objects,
* Example:
* [{
* value: choice value,
* label: choice label
* }]
*/
_addChoiceProperties: function(fieldObject, element, tableName) {
var choiceTable = element.getTableName();
if (new GlideTableHierarchy(choiceTable).getTableExtensions().indexOf(tableName) > -1)
choiceTable = tableName;
var choiceList = GlideChoiceList.getChoiceList(choiceTable, element.getName());
choiceList.addNone();
fieldObject.choiceList = [];
for (var i = 0; i < choiceList.getSize(); i++) {
var choice = choiceList.getChoice(i);
fieldObject.choiceList.push({
value: choice.getValue(),
label: choice.getLabel()
});
}
},
/**
* Return all active COE tables
* Used for select2 COE selector
* @return Array of Objects,
* Example:
* [{
* display: String display value of Topic Category for HR Services,
* table: Array of children HR Service objects
* }]
*/
getActiveCoes: function() {
var coes = [];
var inactiveTables = gs.getProperty("sn_hr_core.inactive_tables", "").split(",");
var coesWithService = this._getCoesWithService();
var caseTables = new GlideTableHierarchy("sn_hr_core_case").getAllExtensions();
for (var i = 0; i < caseTables.length; i++) {
// Skip inactive tables
if (inactiveTables.indexOf(caseTables[i]) != -1 || !coesWithService[caseTables[i]])
continue;
var tableGr = new GlideRecord(caseTables[i]);
// ACL allows users to create ER case through Service Portal,
// however we want to limit create access on case creation pages
if (tableGr.getTableName() === 'sn_hr_er_case' && !gs.hasRole('sn_hr_er.case_writer'))
continue;
this.setInitialCaseFields(tableGr);
if (tableGr.isValid() && tableGr.canRead() && tableGr.canCreate())
coes.push({
display: new GlideRecord(caseTables[i]).getClassDisplayValue(),
table: caseTables[i].toString()
});
}
coes.sort(function(a, b) {
var aDisplay = a.display.toLowerCase();
var bDisplay = b.display.toLowerCase();
if (aDisplay > bDisplay)
return 1;
else if (bDisplay > aDisplay)
return -1;
return 0;
});
return coes;
},
/**
* Returns a map of all COEs with any available HR Service
* @return Object,
* Example: { 'HR_SERVICE_SYS_ID' : true }
*/
_getCoesWithService: function() {
var coes = {};
var hrServices = new GlideAggregate('sn_hr_core_service');
if (this.serviceCondition)
hrServices.addEncodedQuery(this.serviceCondition);
hrServices.addNotNullQuery('topic_detail.topic_category.coe');
hrServices.addQuery('sys_id', 'NOT IN', hr.EXCLUDED_SERVICES);
hrServices.groupBy('topic_detail.topic_category.coe');
hrServices.query();
while(hrServices.next())
coes[hrServices.getValue('topic_detail.topic_category.coe')] = true;
return coes;
},
setInitialCaseFields: function(caseGr) {
caseGr.setValue('opened_by', gs.getUserID());
},
/**
* Return the HR Services for a user, filtered by HR Criteria
* Used for select2 HR Service selector for a single user
* @param userSysId String sys_id of the user to evaluate criteria for
* @param ignoreServiceCondition boolean Ignore this.serviceCondition when querying services
* @return Array of Objects,
* Example:
* [{
* display: String display value of Topic Category for HR Services,
* coe: COE for the service,
* children: Array of children HR Service objects
* Example:
* [{
* display: String display value of HR Service,
* sys_id: String sys_id of HR Service,
* coe: COE for the service,
* template: String sys_id of HR Service's template,
* parent: String Display value of HR Service's Topic Category
* }]
* }]
*/
getServicesForUser: function(userSysId, ignoreServiceCondition) {
// Get the 'active' COEs
var coes = [];
var criteriaResult = {};
var inactiveTables = gs.getProperty("sn_hr_core.inactive_tables", "").split(",");
var caseTables = new GlideTableHierarchy("sn_hr_core_case").getAllExtensions();
for (var j = 0; j < caseTables.length; j++) {
// Skip inactive tables
if (inactiveTables.indexOf(caseTables[j]) != -1)
continue;
var tableGr = new GlideRecord(caseTables[j]);
// Tables returned from getAllExtensions may not exist
if (!tableGr.isValid())
continue;
// ACL allows users to create ER case through Service Portal,
// however we want to limit create access on case creation pages
if (tableGr.getTableName() === 'sn_hr_er_case' && !gs.hasRole('sn_hr_er.case_writer'))
continue;
this.setInitialCaseFields(tableGr);
if (tableGr.canRead() && tableGr.canCreate())
coes.push(caseTables[j].toString());
}
var hrServices = new GlideRecord("sn_hr_core_service");
hrServices.addActiveQuery();
if (!userSysId)
hrServices.addNullQuery("hr_criteria");
hrServices.addNotNullQuery("topic_detail.topic_category.coe");
hrServices.addQuery("topic_detail.topic_category.coe", "IN", coes.join(","));
hrServices.addQuery("value", "!=", hr.BULK_PARENT_CASE_SERVICE);
hrServices.addQuery('sys_id', 'NOT IN', hr.EXCLUDED_SERVICES);
if (!ignoreServiceCondition && this.serviceCondition)
hrServices.addEncodedQuery(this.serviceCondition);
hrServices.orderBy("topic_detail.topic_category.name");
hrServices.orderBy("topic_detail.topic_category.coe");
hrServices.orderBy("name");
hrServices.query();
var result = [];
var categories = {};
var hrCriteria = new sn_hr_core.hr_Criteria();
while (hrServices.next()) {
if (!hrServices.canRead())
continue;
var criteria = hrServices.getValue("hr_criteria");
if (criteria) {
criteria = criteria.split(",");
var userMatchesService = false;
for (var i = 0; i < criteria.length; i++) {
// Save off criteria results and check before reevaluating same criteria
if (criteriaResult.hasOwnProperty(criteria[i])) {
if (criteriaResult[criteria[i]]) {
userMatchesService = true;
break;
}
continue;
} else if (hrCriteria.evaluateById(criteria[i], userSysId)) {
userMatchesService = true;
criteriaResult[criteria[i]] = true;
break;
}
criteriaResult[criteria[i]] = false;
}
if (!userMatchesService)
continue;
}
var categorySysId = hrServices.topic_detail.topic_category.sys_id;
var category = hrServices.topic_detail.topic_category.name.toString();
var coe = hrServices.topic_detail.topic_category.coe.toString();
// ACL allows users to create ER case through Service Portal,
// however we want to limit create access on case creation pages
if (coe === 'sn_hr_er_case' && !gs.hasRole('sn_hr_er.case_writer'))
continue;
var coeDisplayName = new GlideRecord(coe).getClassDisplayValue();
if (!categories[categorySysId]) {
categories[categorySysId] = {
display: category,
coe: coe,
children: [],
sys_id: categorySysId + ''
};
result.push(categories[categorySysId]);
}
categories[categorySysId].children.push({
sys_id : hrServices.getUniqueValue(),
coe: coe,
coeDisplayName: coeDisplayName,
display : hrServices.getDisplayValue(),
template : hrServices.getValue("template"),
parent : category
});
}
return result;
},
/**
* Used By hr_CaseAjax to check if the subject person has the access to the given HR Service
*/
hasAccessForService: function(userSysId, ignoreServiceCondition, service_id) {
var hrServices = new GlideRecord("sn_hr_core_service");
hrServices.addActiveQuery();
hrServices.get(service_id);
hrServices.query();
if (hrServices.next()) {
if (!hrServices.canRead())
return false;
var criteria = hrServices.getValue("hr_criteria");
if (!criteria)
return true;
var hrCriteria = new sn_hr_core.hr_Criteria();
criteria = criteria.split(",");
var userMatchesService = false;
var criteriaResult = {};
for (var i = 0; i < criteria.length; i++) {
// Save off criteria results and check before reevaluating same criteria
if (criteriaResult.hasOwnProperty(criteria[i])) {
if (criteriaResult[criteria[i]]) {
userMatchesService = true;
break;
}
continue;
} else if (hrCriteria.evaluateById(criteria[i], userSysId)) {
userMatchesService = true;
criteriaResult[criteria[i]] = true;
break;
}
criteriaResult[criteria[i]] = false;
}
return userMatchesService;
}
return false;
},
/**
* Get the employee reference to this.userObjectTable for a @param userSysId
* @param userSysId String sys_id of the user to get the display reference for
* @param columnLabel String display name of the column this user is referenced on
* @return Object Display reference information,
* Example:
* {
* ev_table : table of the employee verification record,
* ev_sys_id : sys_id of the employee verification record,
* ev_tooltip : tooltip of the employee verification record
* }
*/
getEmployeeReference: function(userSysId, columnLabel) {
var employeeReference = {};
var employeeGr = new GlideRecordSecure(this.userObjectTable);
if (employeeGr.isValid() && employeeGr.get(this.userColumn, userSysId)) {
employeeReference.ev_table = employeeGr.getTableName();
employeeReference.ev_sys_id = employeeGr.getUniqueValue();
employeeReference.ev_tooltip = gs.getMessage("Preview record for field: {0}", columnLabel);
}
return employeeReference;
},
/** Determine whether an array of users contains a vip user
* @param userArr array List of user sys_id's to check for vip status
* @return boolean Whether @param userArr contains a VIP user
*/
containsVipUser: function(userArr) {
if (!userArr || !userArr.length)
return false;
var grUser = new GlideRecord("sys_user");
grUser.addQuery("vip", true);
grUser.addQuery("sys_id", "IN", userArr.toString());
grUser.setLimit(1);
grUser.query();
return grUser.hasNext();
},
/** Check if ducplicate case exists for
* @param taskTable String table name
* @param hrSercvice String sys_id of HR service (sn_hr_core_service)
* @param caseUserId String sys_id of user (sys_user)
* @param isOpenedFor Boolean True if the caseUserId is the opened_for, false if subject_person
* @return Object {
* boolean true if duplicate case exits within configured time (sys_properties)
* GlideDateTime in String to filter query
* }
*/
checkDuplicate: function(taskTable, hrService, caseUserId, isOpenedFor) {
var gdt = new GlideDateTime();
var createNewCaseTimeOut = gs.getProperty('sn_hr_core.duplicate_hr_case_time_out', gdt);
gdt.addDaysLocalTime(-createNewCaseTimeOut);
var ga = new GlideAggregate(taskTable);
ga.addQuery('active', 'true');
ga.addQuery('sys_created_on', '>=', gdt);
ga.addQuery('hr_service', hrService);
if (isOpenedFor)
ga.addQuery('opened_for', caseUserId);
else
ga.addQuery('subject_person', caseUserId);
ga.query();
return {
showModal: ga.getRowCount() > 0? true :false,
filterTime: gdt.toString()
};
},
/** Create a task for given table and fields
* @param table String Name of task table to create (can be overwritten by hr_service field)
* @param fields Object Map of field objects, eg { 'hr_service': { value: 'SYS_ID' } }
* @return Object Object representing created task (empty if didn't create), e.g. { 'table': 'TABLE_NAME', 'sys_id': 'SYS_ID', 'can_read': false }
*/
createTask: function(table, fields, includeErrors) {
var errors = [];
var msg = {};
var addError = gs.addErrorMessage;
if (includeErrors) {
addError = function(msg) {
errors.push(msg);
};
msg = {errors: errors};
}
var template = '';
// Replace @param table with HR Service COE
if (fields.hasOwnProperty('hr_service')) {
if (fields.hasOwnProperty('opened_for') && fields.opened_for.mandatory && !fields.opened_for.value) {
addError(gs.getMessage('Failed to insert record. Opened for value is empty.'));
return msg;
}
var serviceGr = new GlideRecord('sn_hr_core_service');
if (!serviceGr.isValid() || !serviceGr.get(fields['hr_service'].value)) {
addError(gs.getMessage(
'Failed to retrieve service. HR Service does not exist for ' + fields['hr_service'].value));
return msg;
}
table = serviceGr.getElement('topic_detail.topic_category.coe').toString();
template = serviceGr.getElement('template').toString();
}
// Create task record from input payload
var newTaskGr = new GlideRecordSecure(table);
newTaskGr.newRecord();
this.setInitialCaseFields(newTaskGr);
if (!newTaskGr.isValid() || !newTaskGr.canCreate()) {
addError(gs.getMessage('Failed to insert record. ' + newTaskGr.getLastErrorMessage()));
return msg;
}
// Call applyBefore now so that fields with default values are overwritten by template, but user changes
// overwrite template still
if (template)
new sn_hr_core.hr_TemplateUtils().applyBefore(template, newTaskGr, true);
// Set all input fields
for (var key in fields) {
var ele = newTaskGr.getElement(key);
if (newTaskGr.isValidField(key) && ele != null && ele.canRead() && ele.canCreate()) {
if (fields[key].setAsDisplayValue)
newTaskGr[key].setDisplayValue(fields[key].value);
else {
newTaskGr.setValue(key, fields[key].value); // Duration fields are not set by setting the element
newTaskGr[key] = fields[key].value; // Journal fields are not set using GlideRecord.setValue
}
}
}
// Set priority if VIP and priority not on form
if (!fields.hasOwnProperty('priority')) {
var userArray = [];
if (fields.hasOwnProperty('opened_for') && fields['opened_for'].value)
userArray.push(fields['opened_for'].value);
if (fields.hasOwnProperty('subject_person') && fields['subject_person'].value)
userArray.push(fields['subject_person'].value);
if (this.containsVipUser(userArray))
newTaskGr.setValue('priority',
String(gs.getProperty('sn_hr_core.hr_vip_default_priority', hr.DEFAULT_HIGH_PRIORITY) || '2'));
}
if (newTaskGr.assigned_to != '' && newTaskGr.assignment_group != '' &&
!(new hr_CoreUtils()).hasValidAssignee(newTaskGr)) {
addError(gs.getMessage('The assignee is not a member of the assignment group'));
return msg;
}
if (newTaskGr.insert()) {
if (!newTaskGr.get(newTaskGr.getUniqueValue()) || !newTaskGr.canRead()) {
gs.addInfoMessage(gs.getMessage(
'You do not have permission to read the created record. {0}', newTaskGr.getLastErrorMessage()));
return {
can_read: false
};
}
return {
table: newTaskGr.getTableName(),
sys_id: newTaskGr.getUniqueValue()
};
}
addError(gs.getMessage('Failed to insert record. ' + newTaskGr.getLastErrorMessage()));
return msg;
},
/** Gets the Verification Fields from Case Configuration
* @param userId String The ID of the User we are verifying
* @return verificationFields Object
* {
* display : display value of a field,
* label : label of a field,
* value : value of a field,
* column_name : column name of a field,
* max_length : max length of a field,
* internal_type : internal type of a field,
* type : internal type of a field (used for DEO angular directive)
* referringRecordId : sys_id of record from where field object is created,
* readonly : if field is readonly (set to true)
* }
*/
getVerificationFields: function(userID) {
var profileTable = this.userObjectTable;
var profileRecord = new GlideRecord(profileTable);
profileRecord.initialize();
//Verification Fields
var verificationFields = {};
if (profileRecord.isValid() && profileRecord.get('user', userID) && profileRecord.canRead()){
for(var k in this.fields)
verificationFields[k] = this.getFieldObjects(profileRecord, this.fields[k], true);
} else {
var userRecord = new GlideRecord(this.sysUserTable);
userRecord.initialize();
if (userRecord.isValid() && userRecord.get('sys_id', userID) && userRecord.canRead())
for (var m in this.fields)
verificationFields[m] = this.getFieldObjects(userRecord, this.fields[m], false);
}
this._setFieldsReadOnly(verificationFields.left_fields, "true");
this._setFieldsReadOnly(verificationFields.right_fields, "true");
return verificationFields;
},
/** Adds readonly attribute to a list of fields
* @param listOfFields List Set of fields to set attribute on
* @param isReadOnly Boolean True if field is readonly, false if not.
* @return listOfField List Fields now have readonly attribute.
*/
_setFieldsReadOnly: function(listOfFields, isReadOnly){
if (listOfFields)
for(var k in listOfFields)
listOfFields[k]["readonly"] = isReadOnly;
return listOfFields;
},
/** Helper method for fix script to update
* legacy and native case creation configurations
*/
updateCaseCreation: function(){
this._updateCaseCreationConfig();
this._updateCaseCreationServiceConfig();
},
/** Helper method for updateCaseCreation to update
* case creation configuration
*/
_updateCaseCreationConfig: function(){
var errorUtil = new sn_hr_core.ErrorUtil();
try {
var gr = new GlideRecord('sn_hr_core_config_case_creation');
gr.setLimit(1);
gr.query();
errorUtil.validateGrForError(gr);
if (gr.next()) {
var leftFields = gr.getValue(this.LEFT_TASK_FIELDS);
var rightFields = gr.getValue(this.RIGHT_TASK_FIELDS);
if (leftFields === null && rightFields === 'opened_for,subject_person') {
gr.setValue(this.LEFT_TASK_FIELDS, 'opened_for');
gr.setValue(this.RIGHT_TASK_FIELDS, 'subject_person');
if (gr.update() === null)
throw errorUtil.throwGrError(gr);
}
}
}
catch (error) {
throw errorUtil.handleExceptionMethod('_updateCaseCreationConfig', error);
}
},
/** Helper method for updateCaseCreation to update
* Tuition Reimbursement configuration record
*/
_updateCaseCreationServiceConfig: function(){
var errorUtil = new sn_hr_core.ErrorUtil();
var i = 0;
var len = this.CASE_CREATION_SERVICE_CONFIG_SYSID.length;
while (i < len) {
try {
var gr = new GlideRecord('sn_hr_core_config_case_creation_service');
if(!gr.get(this.CASE_CREATION_SERVICE_CONFIG_SYSID[i])) {
i++;
continue;
}
errorUtil.validateGrForError(gr);
var leftFields = gr.getValue(this.LEFT_TASK_FIELDS);
var rightFields = gr.getValue(this.RIGHT_TASK_FIELDS);
if (i === 0 && leftFields === 'school_program_name,course_title,course_justification' && rightFields === 'opened_for,subject_person,course_start_date,course_end_date,course_cost') {
gr.setValue(this.LEFT_TASK_FIELDS, 'opened_for,school_program_name,course_title,course_justification');
gr.setValue(this.RIGHT_TASK_FIELDS, 'subject_person,course_start_date,course_end_date,course_cost');
if (gr.update() === null)
throw errorUtil.throwGrError(gr);
}
else if (i === 1 && leftFields === 'ref_sn_hr_er_case.locked' && rightFields === 'opened_for,subject_person') {
gr.setValue(this.LEFT_TASK_FIELDS, 'opened_for,locked');
gr.setValue(this.RIGHT_TASK_FIELDS, 'subject_person');
if (gr.update() === null)
throw errorUtil.throwGrError(gr);
}
else if (i === 2 && leftFields === null && rightFields === 'opened_for,locked') {
gr.setValue(this.LEFT_TASK_FIELDS, 'opened_for');
gr.setValue(this.RIGHT_TASK_FIELDS, 'locked');
if (gr.update() === null)
throw errorUtil.throwGrError(gr);
}
}
catch (error) {
throw errorUtil.handleExceptionMethod('_updateCaseCreationServiceConfig', error);
}
i++;
}
},
type: 'hr_CaseCreation'
};
Sys ID
687d7d8deb6f3200a9e7e26ac106fee0