Skip to content

Instantly share code, notes, and snippets.

@jmbauguess
Last active September 1, 2015 02:20
Show Gist options
  • Save jmbauguess/1bb08453fa736fc77b71 to your computer and use it in GitHub Desktop.
Save jmbauguess/1bb08453fa736fc77b71 to your computer and use it in GitHub Desktop.
Refactoring the Approval Events (task) Business Rule into a script include
/**
* @description Determines what event to use when the approval state changes on a task record
* @namespace
* @type {Class}
*/
var ApprovalEventsHandler = Class.create();
ApprovalEventsHandler.prototype = {
/**
* @description Cancelled state value
* @type {String}
*/
CANCELLED : 'cancelled',
/**
* @description Requested state value
* @type {String}
*/
REQUESTED : 'requested',
/**
* @description Approved state value
* @type {String}
*/
APPROVED : 'approved',
/**
* @description Rejection state value
* @type {String}
*/
REJECTED : 'rejected',
/**
* @description Request table name
* @type {String}
*/
REQUEST: 'sc_request',
/**
* @description Catalog Task table name
* @type {String}
*/
SCTASK : 'sc_task',
/**
* @description Requested Item table name
* @type {String}
*/
RITM: 'sc_req_item',
/**
* @description The Rejected By Other event
* @type {String}
*/
OTHER_EVENT: 'approval.rejected.by.other',
/**
* @description The Generic approval cancellation
* @type {String}
*/
CANCELLED_EVENT : 'approval.cancelled',
/**
* @description The Generic approval creation
* @type {String}
*/
REQUESTED_EVENT : 'approval.inserted',
/**
* @description The Generic approval accepted
* @type {String}
*/
APPROVED_EVENT : 'approval.accepted',
/**
* @description the Generic approval rejection
* @type {String}
*/
REJECTED_EVENT : 'approval.rejected',
/**
* @description Maps approval states to events
* @type {Object}
*/
EVENT_MAP: {
'cancelled' : 'approval.cancelled',
'requested' : 'approval.inserted',
'approved' : 'approval.accepted',
'rejected' : 'approval.rejected'
},
/**
* @description Processes the event for approvals
* @param {GlideRecord} record The approval record
*/
processEvent: function(record) {
if (record.state.toString() !== this.APPROVED) {
this.handleNotApproved(record);
} else if (record.state.toString() === this.APPROVED) {
this.handleApproved(record);
}
if (this.shouldIUpdateTask(record)) {
this.updateTask(record,
this.makeJournalEntry(record.approver.getDisplayValue() +
" updated the task.", record.comments));
}
},
/**
* @description Handles the event when it's not approved
* @param {GlideRecord} record The approval record
*/
handleNotApproved: function(record) {
var event = this.determineEvent(record.state.toString(),
record.sysapproval.sys_class_name.toString()),
ritm = this.getRequestedItem(record.sysapproval);
gs.eventQueue(event, record, gs.getUserID(), gs.getUserName());
if (ritm.approval.toString() === this.REJECTED) {
this.notifyMyFriends(record);
}
},
/**
* @description Handles the approval record when the item is approved;
* in this case, we care too if the record it's for is "approved"
* @param {GlideRecord} record The approval record
*/
handleApproved: function(record) {
var ritm = this.getRequestedItem(record.sysapproval);
if (ritm.approval.toString() === this.APROVED) {
var event = this.determineEvent(record.state.toString(),
record.sysapproval.sys_class_name.toString());
gs.eventQueue(event, ritm, record.sysapproval.request.requested_for,
gs.getUserName());
}
},
/**
* @description Determines if the record is a request
* @param {String} name The name of the task class
* @return {Boolean} True if it's a request
*/
isRequest: function(name) {
return name === this.REQUEST;
},
/**
* @description Determines if the record is a catalog task
* @param {String} name The name of the task class
* @return {Boolean} True if it's a catalog task
*/
isCatalogTask: function(name) {
return name === this.SCTASK;
},
/**
* @description Gets the correct record for the approval accepted event
* @param {String} sysId The sys_id of a requested item
* @return {GlideRecord} The requested item GlideRecord
*/
getRequestedItem: function(sysId) {
var ritm = new GlideRecord('sc_req_item');
ritm.get(sysId);
return ritm;
},
/**
* @description Determines the event to use
* @param {String} type The state of the approval
* @param {String} name The name of the record clsas
* @return {String} The event to use
*/
determineEvent: function(type, name) {
var event = this.EVENT_MAP[type];
if (event === undefined) {
return '';
}
if (this.isRequest(name)) {
return "request." + event;
} else if (this.isCatalogTask(name)) {
return "sc_task." + event;
} else {
return event;
}
},
/**
* @description Adds comments to a journal entry
* @param {String} journal The new comment
* @param {String} comments The current comments
* @return {String} The new journal entry
*/
makeJournalEntry: function(journal, comments) {
if (comments) {
return journal += " Comments " + comments;
} else {
return journal;
}
},
/**
* @description Determines if the task should be updated;
* Group approvals and workflow approvals with a proprety set are the only ones that get updated
* @param {GlideRecord} me The approval record
*/
shouldIUpdateTask: function(me) {
if (!me.group.nil() || (!me.wf_activity.nil() &&
(gs.getProperty("glide.workflow.user_approval_history") != "true"))) {
return;
}
},
/**
* @description Updates a task related to an approval
* @param {GlideRecord} me An approval record
* @param {String} journal A journal field value
* @return {String} The sys_id of the updated record
*/
updateTask: function(me, journal) {
var task = new GlideRecord('task');
if (task.get(me.sysapproval)) {
if (!me.wf_activity.nil()) {
task.setWorkflow(false);
}
task.approval_history.setJournalEntry(journal);
return task.update();
}
return '';
},
/**
* @description Notifies other approvers when an approval is rejected
* @param {GlideRecord} me The approval record
*/
notifyMyFriends: function(me) {
var friends = new GlideRecord('sysapproval_approver');
friends.addQuery('sysapproval', me.sysapproval);
friends.query();
while (friends.next()) {
if (friends.approver.toString() !== me.approver.toString()) {
gs.eventQueue(this.OTHER_EVENT, me, friends.approver);
}
}
},
'type' : 'ApprovalEventsHandler'
};
(function(){
var unit = new SNUnit();
var aeh = new ApprovalEventsHandler();
unit.framework.setTableName('sysapproval_approver');
unit.test("Given a type and name, we get an event", function() {
unit.framework.setFunctionName('determineEvent');
unit.framework.assertEqual(aeh.determineEvent('requested', 'sc_req_item'), aeh.REQUESTED_EVENT, "A ritm event is " + aeh.REQUESTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('requested', 'sc_request'), "request." + aeh.REQUESTED_EVENT, "A request event is request." + aeh.REQUESTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('requested', 'sc_task'), "sc_task." + aeh.REQUESTED_EVENT, "A catalog task event is sc_task." + aeh.REQUESTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('','sc_req_item'), '', "The event is empty because we had an invalid state");
unit.framework.assertEqual(aeh.determineEvent('requested', ''), aeh.REQUESTED_EVENT, "Even with out a table, The event is " + aeh.REQUESTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('cancelled', 'sc_req_item'), aeh.CANCELLED_EVENT, "A ritm event is " + aeh.CANCELLED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('cancelled', 'sc_request'), "request." + aeh.CANCELLED_EVENT, "A request event is request." + aeh.CANCELLED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('cancelled', 'sc_task'), "sc_task." + aeh.CANCELLED_EVENT, "A catalog task event is sc_task." + aeh.CANCELLED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('cancelled', 'change_request'), aeh.CANCELLED_EVENT, "The event is " + aeh.CANCELLED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('','sc_req_item'), '', "The event is empty because we had an invalid state");
unit.framework.assertEqual(aeh.determineEvent('cancelled', ''), aeh.CANCELLED_EVENT, "Even with out a table, The event is " + aeh.CANCELLED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('approved', 'sc_req_item'), aeh.APPROVED_EVENT, "A ritm event is " + aeh.APPROVED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('approved', 'sc_request'), "request." + aeh.APPROVED_EVENT, "A request event is request." + aeh.APPROVED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('approved', 'sc_task'), "sc_task." + aeh.APPROVED_EVENT, "A catalog task event is sc_task." + aeh.APPROVED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('approved', 'change_request'), aeh.APPROVED_EVENT, "The event is " + aeh.APPROVED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('','sc_req_item'), '', "The event is empty because we had an invalid state");
unit.framework.assertEqual(aeh.determineEvent('approved', ''), aeh.APPROVED_EVENT, "Even with out a table, The event is " + aeh.APPROVED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('rejected', 'sc_req_item'), aeh.REJECTED_EVENT, "A ritm event is " + aeh.REJECTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('rejected', 'sc_request'), "request." + aeh.REJECTED_EVENT, "A request event is request." + aeh.REJECTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('rejected', 'sc_task'), "sc_task." + aeh.REJECTED_EVENT, "A catalog task event is sc_task." + aeh.REJECTED_EVENT);
unit.framework.assertEqual(aeh.determineEvent('','sc_req_item'), '', "The event is empty because we had an invalid state");
unit.framework.assertEqual(aeh.determineEvent('rejected', ''), aeh.REJECTED_EVENT, "Even with out a table, The event is " + aeh.REJECTED_EVENT);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment