Name

global.ChangeTypeChgReqAPISNC

Description

SNC Code for the ChangeTypeChgReqAPI class.

Script

var ChangeTypeChgReqAPISNC = Class.create();

ChangeTypeChgReqAPISNC.ENFORCE_DATA_REQ_PROP = "com.snc.change_management.enforce_data_requirements";

ChangeTypeChgReqAPISNC.prototype = {
  SUCCESSFUL: "successful",
  UNSUCCESSFUL: "unsuccessful",
  SUCCESSFUL_ISSUES: "successful_issues",
  REQUESTED: "requested",
  APPROVED: "approved",
  REJECTED: "rejected",
  NOT_REQUESTED: "not requested",
  EMERGENCY_WORKFLOW: ChangeRequest.prototype.EMERGENCY_WORKFLOW || "Change Request - Emergency",
  STANDARD_WORKFLOW: ChangeRequest.prototype.STANDARD_WORKFLOW || "Change Request - Standard",
  NORMAL_WORKFLOW: ChangeRequest.prototype.NORMAL_WORKFLOW || "Change Request - Normal",

  initialize: function(changeGr) {
  	this._log = new GSLog(ChangeCommon.LOG_PROPERTY, this.type);
  	this._gr = changeGr;
  	this._stateHandler = new ChangeRequestStateHandler(this._gr);
  },

  isInitialState: function() {
  	return this.isNew();
  },
  
  revertToInitialState: function() {
  	this.setNew();
  	return this.changesToNew();
  },
  
  // If the change is in a terminal state (no transitions).
  // If not using a model, is the sames as 'isClosed || isCancelled'.
  isTerminalState: function() {
  	return this.isClosed() || this.isCanceled();
  },
  
  // Returns true if the state of the current record is the same as stateValue
  isState: function(stateValue) {
  	if (!stateValue)
  		return false;
  	
  	return stateValue === this._gr.getValue("state");
  },
  
  //  No equivalent in base implementation
  isNextState: function(stateValue) {
  	return this.canMoveTo(stateValue) && this.getNextStates().indexOf(stateValue) !== -1;
  },

  isNextManualState: function(stateValue) {
  	return this.canMoveTo(stateValue) && this.getNextManualStates().indexOf(stateValue) !== -1;
  },

  getNextStates: function() {
  	var stateValues = [];
  	var nextStates = this._stateHandler.getAvailableStates();
  	if (nextStates) {
  		nextStates.forEach(function(nextState) {
  			stateValues.push(this._stateHandler.getStateValue(nextState));
  		}, this);
  	}
  	return stateValues;
  },

  getNextManualStates: function() {
  	var stateValues = [];
  	var nextStates = this._stateHandler.getNextStates();
  	if (nextStates) {
  		nextStates.forEach(function(nextState) {
  			stateValues.push(this._stateHandler.getStateValue(nextState));
  		}, this);
  	}
  	return stateValues;
  },

  moveTo: function(stateValue) {
  	if (!stateValue)
  		return false;

  	stateValue = this._stateHandler.getStateName(stateValue) || stateValue;
  	return this._stateHandler.moveTo(stateValue);
  },
  
  canMoveTo: function (stateValue) {
  	if (!stateValue)
  		return false;
  	
  	stateValue = this._stateHandler.getStateName(stateValue) || stateValue;
  	return this._stateHandler.canMoveTo(stateValue);
  },
  
  //  No equivalent in base implementation
  evaluateMoveTo: function (stateValue, returnAll) {
  	var transitions = {
  		"from_state": this._gr.getValue("state"),
  		"to_state": stateValue,
  		"transition_available": this.canMoveTo(stateValue)
  	};
  	return returnAll ? [transitions] : transitions;
  },
  
  // Allow implementation in Implement and Review states
  canImplement: function() {
  	return this.isImplement() || this.isReview();
  },
  
  /**
   * New
   */
  isNew: function() {
  	// Change state model's label is New but that's a Javascript reserved word so draft is used instead
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.DRAFT);
  },

  changesToNew: function() {
  	return this._gr.state.changes() && this.isNew();
  },

  changesFromNew: function() {
  	return this._gr.state.changesFrom(this._stateHandler.getStateValue(ChangeRequestStateHandler.DRAFT));
  },

  setNew: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.DRAFT);
  },

  // use toNew to avoid using the reserved word 'new'
  toNew: function() {
  	this.setNew();
  	return this._insertUpdate();
  },

  /**
  * Revert the Change Request to New by invoking the state model handler
  * Delete the workflow context associated to the current change type
  *
  * Return false if the state model does not allow the modification
  * Return true (and clear the On Hold field) if the Change Request has been successfully reverted to New
  */
  revertToNew: function() {
  	this.setNew();
  	if (!this.changesToNew())
  		return false;
  	this.deleteDefaultWorkflowContext();
  	this.setValue('on_hold', false);
  	this.update();
  	return true;
  },

  /**
   * Assess -- used internally by the change request workflows.
   * 
   * To move a change (regardless of type) to the state after New call requestApproval instead
   */
  isAssess: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.ASSESS);
  },

  changesToAssess: function() {
  	return this._gr.state.changes() && this.isAssess();
  },

  setAssess: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.ASSESS);
  },

  assess: function() {
  	this.setAssess();
  	return this._insertUpdate(); 
  },

  /**
   * Authorize -- used internally by the change request workflows.
   * 
   * To move a change (regardless of type) to the state after New call requestApproval instead
   */
  isAuthorize: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.AUTHORIZE);
  },

  changesToAuthorize: function() {
  	return this._gr.state.changes() && this.isAssess();
  },

  setAuthorize: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.AUTHORIZE);
  },

  authorize: function() {
  	this.setAuthorize();
  	return this._insertUpdate();
  },

  /**
   * Scheduled -- used internally by the change request workflows.
   * 
   * To move a change (regardless of type) to the state after New call requestApproval instead
   */
  isScheduled: function() {
  	return this._gr.getValue("state") === this._stateHandler.getStateValue(ChangeRequestStateHandler.SCHEDULED);
  },

  changesToScheduled: function() {
  	return this._gr.state.changes() && this.isScheduled();
  },

  setScheduled: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.SCHEDULED);
  },

  scheduled: function() {
  	this.setScheduled();
  	return this._insertUpdate();
  },

  /**
   * Implement
   */
  isImplement: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.IMPLEMENT);
  },

  changesToImplement: function() {
  	return this._gr.state.changes() && this.isImplement();
  },

  setImplement: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.IMPLEMENT);
  },

  implement: function() {
  	this.setImplement();
  	return this._insertUpdate();
  },

  /**
   * Review
   */
  isReview: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.REVIEW);
  },

  changesToReview: function() {
  	return this._gr.state.changes() && this.isReview();
  },

  setReview: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.REVIEW);
  },

  review: function() {
  	this.setReview();
  	return this._insertUpdate();
  },

  /**
   * Close
   */
  isClosed: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.CLOSED);
  },

  changesToClosed: function() {
  	return this._gr.state.changes() && this.isClosed();
  },

  isClosedSuccessful: function() {
  	return this.isClosed() && this._gr.close_code + "" === this.SUCCESSFUL;
  },

  isClosedSuccessfulWithIssues: function() {
  	return this.isClosed() && this._gr.close_code + "" === this.SUCCESSFUL_ISSUES;
  },

  isClosedUnsuccessful: function() {
  	return this.isClosed() && this._gr.close_code + "" === this.UNSUCCESSFUL;
  },

  setClose: function(closeCode, closeNotes) {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.CLOSED);

  	if (closeNotes)
  		this._gr.close_notes = closeNotes;

  	switch (closeCode) {
  		case this.UNSUCCESSFUL:
  			this._gr.close_code = this.UNSUCCESSFUL;
  			break;
  		case this.SUCCESSFUL_ISSUES:
  			this._gr.close_code = this.SUCCESSFUL_ISSUES;
  			break;
  		default:
  			this._gr.close_code = this.SUCCESSFUL;
  	}
  },

  close: function(closeCode, closeNotes) {
  	this.setClose(closeCode, closeNotes);
  	return this._insertUpdate();
  },

  closeSuccessful: function(closeNotes) {
  	if (!closeNotes)
  		closeNotes = gs.getMessage("Change closed successfully");

  	return this.close(this.SUCCESSFUL, closeNotes);
  },

  closeSuccessfulWithIssues: function(closeNotes) {
  	if (!closeNotes)
  		closeNotes = gs.getMessage("Change closed successfully with issues");

  	return this.close(this.SUCCESSFUL_ISSUES, closeNotes);
  },

  closeUnsuccessful: function(closeNotes) {
  	if (!closeNotes)
  		closeNotes = gs.getMessage("Change closed unsuccessfully");

  	return this.close(this.UNSUCCESSFUL, closeNotes);
  },

  /**
   * Cancel
   */
  isCanceled: function() {
  	return this._gr.state + "" === this._stateHandler.getStateValue(ChangeRequestStateHandler.CANCELED);
  },

  changesToCanceled: function() {
  	return this._gr.state.changes() && this.isCanceled();
  },

  setCancel: function() {
  	this._stateHandler.moveTo(ChangeRequestStateHandler.CANCELED);
  },

  cancel: function() {
  	this.setCancel();
  	return this._insertUpdate();
  },

  /**
   * Approvals
   */
  isApprovalRequested: function() {
  	var state = this._gr.state + "";
  	var assess = this._stateHandler.getStateValue(ChangeRequestStateHandler.ASSESS);
  	var authorize = this._stateHandler.getStateValue(ChangeRequestStateHandler.AUTHORIZE);

  	return (state === assess || state === authorize) && this._gr.approval + "" === this.REQUESTED;
  },

  isApproved: function() {
  	var state = this._gr.state + "";
  	var assess = this._stateHandler.getStateValue(ChangeRequestStateHandler.ASSESS);
  	var authorize = this._stateHandler.getStateValue(ChangeRequestStateHandler.AUTHORIZE);

  	return !this.isNew() && state !== assess && state !== authorize && this._gr.approval + "" === this.APPROVED;
  },

  isRejected: function() {
  	return this.isNew() && this._gr.approval + "" === this.REJECTED;
  },

  setRequestApproval: function() {
  	if (this.isNew())
  		return this._stateHandler.next();
  	
  	return false;
  },

  requestApproval: function() {
  	if (this.setRequestApproval())
  		return this._insertUpdate();
  	
  	return false;
  },

  _insertUpdate: function() {
  	return (this._gr.isNewRecord() ? this.insert() : this.update());
  },

  setValue: function(name, value) {
  	this._gr.setValue(name, value);
  },
  
  getValue: function(name) {
  	return this._gr.getValue(name);
  },

  setDisplayValue: function(name, value) {
  	this._gr.setDisplayValue(name, value);
  },

  getDisplayValue: function(name) {
  	return this._gr.getDisplayValue(name);
  },
  
  insert: function() {
  	var id = this._gr.insert();

  	var gr = new GlideRecord(ChangeRequest.CHANGE_REQUEST);
  	if (!gr.get(id))
  		this._gr = null;

  	this.initialize(gr);
  },

  update: function() {
  	this._gr.update();
  },
  
  refreshGlideRecord: function() {
  	var gr = new GlideRecord(ChangeRequest.CHANGE_REQUEST);
  	if (!gr.get(this._gr.getUniqueValue()))
  		this._gr = null;


  	this.initialize(gr);
  },

  modifyType: function(previousType) {	
  	if (JSUtil.nil(this._gr) || JSUtil.nil(previousType))
  		return;
  	
  	// Modifying Change Type from 'anything' to 'Standard' is not allowed
  	if (this.getValue("type") == ChangeRequest.STANDARD)
  		return;
  	
  	//Deleting the workflow context related to the previous Change Type
  	var workflowName = this._getWorkflowFromType(previousType);
  	this._deleteWorkflowContext(workflowName);
  	
  	if (previousType == ChangeRequest.STANDARD)
  		this._gr.approval = this.NOT_REQUESTED;
  },

  deleteDefaultWorkflowContext: function() {
  	// delete default workflow context based on current type
  	var workflowName = this._getWorkflowFromType(this.getValue('type'));
  	this._deleteWorkflowContext(workflowName);
  },

  _updateStdStats: function(){
  	var util = new StdChangeUtils();
  	var stdChgProducerVersion = this.getValue(util.ATTR_STD_CHG_PRODUCER_VERSION);
  	if (!JSUtil.nil(stdChgProducerVersion)){
  		this.setValue(util.ATTR_STD_CHG_PRODUCER_VERSION, '');
  		util.updateVersionStats(stdChgProducerVersion.getUniqueValue());
  	}
  },

  _deleteWorkflowContext: function(workflowName){
  	var workflow = new Workflow();
  	var wfContext = workflow.getContexts(this._gr);
  	while (wfContext.next()) {
  		if (wfContext.workflow_version.nil() || wfContext.state + "" !== "executing")
  			continue;
  		
  		var wfVersion = wfContext.workflow_version.getRefRecord();
  		if (wfVersion.name + "" === workflowName) {
  			wfContext.deleteRecord();
  			break;
  		}
  	}
  },

  _getWorkflowFromType: function(type){
  	var workflow = ""; 
  	switch (type){
  		case ChangeRequest.EMERGENCY:
  			workflow = this.EMERGENCY_WORKFLOW;
  			break;
  		case ChangeRequest.NORMAL:
  			workflow = this.NORMAL_WORKFLOW;
  			break;
  		case ChangeRequest.STANDARD:
  			workflow = this.STANDARD_WORKFLOW;
  			break;
  	}
  	return workflow;
  },

  toString: function() {
  	return JSON.stringify(this.toJS());
  },

  toJS: function() {
  	return ChangeCommon.toJS(this._gr);
  },

  deleteRecord: ChangeCommon.methods.deleteRecord,

  getGlideRecord: ChangeCommon.methods.getGlideRecord,

  setValues: ChangeCommon.methods.setValues,

  canWriteTo: ChangeCommon.methods.canWriteTo,

  type: 'ChangeTypeChgReqAPISNC'
};

ChangeTypeChgReqAPISNC.newNormal = function() {
  return ChangeTypeChgReqAPI.newChange(ChangeRequest.NORMAL);
};

ChangeTypeChgReqAPISNC.newStandard = function() {
  return ChangeTypeChgReqAPI.newChange(ChangeRequest.STANDARD);
};

ChangeTypeChgReqAPISNC.newEmergency = function() {
  return ChangeTypeChgReqAPI.newChange(ChangeRequest.EMERGENCY);
};

ChangeTypeChgReqAPISNC.newChange = function(type) {
  var changeGr = new GlideRecord(ChangeRequest.CHANGE_REQUEST);
  changeGr.newRecord();
  
  changeGr.setValue("state", new ChangeRequestStateHandler().getStateValue(ChangeRequestStateHandler.DRAFT));

  if (JSUtil.notNil(type))
  	changeGr.setValue("type", type);

  return new ChangeRequest(changeGr);
};

Sys ID

386de6bf5387101034d1ddeeff7b12ad

Offical Documentation

Official Docs: