Name

global.TransferOrderStageHandler

Description

Changes the Transfer Order Stages and the Transfer Order Lines Stages

Script

var TransferOrderStageHandler = Class.create();

TransferOrderStageHandler.prototype = {
  initialize : function() {
  },

  /*
   * Determines whether a specific staging button should be visible or not.
   * Note: transferOrder can refer to a transfer order or a transfer order
   * line
   */
  isUIActionAllowed : function(transferOrder, requestedUIAction) {
  	if (transferOrder.stage == 'draft' &&
  			requestedUIAction == 'requested' &&
  			this._getChildrenInStage(transferOrder, 'draft') > 0)
  		return true;
  	else if ((transferOrder.stage == 'shipment_preparation' ||
  			transferOrder.stage == 'requested' || transferOrder.stage == 'draft') &&
  			requestedUIAction == 'cancellation' &&
  			transferOrder.asset.nil() == false) {
  		return true;
  	} else if (requestedUIAction == 'shipment_preparation') {
  		if ((transferOrder.stage == 'requested' ||
  				this._getChildrenInStage(transferOrder, 'requested') > 0))
  			return true;
  	} else if ((transferOrder.stage == 'shipment_preparation' || transferOrder.stage == 'partially_shipped') &&
  			(requestedUIAction == 'ship')) {
  		if (this._getChildrenInStage(transferOrder, 'shipment_preparation') > 0 &&
  				this._getChildrenInStage(transferOrder, 'requested') === 0)
  			return true;
  	} else if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.work_management') &&
  			requestedUIAction == 'delivered' &&
  			!transferOrder.transfer_order.service_order_task.nil() &&
  			!transferOrder.transfer_order.service_order_task.assigned_to.nil() &&
  			',17,18,'.indexOf(','+transferOrder.transfer_order.service_order_task.state+',') != -1) {
  		if (transferOrder.stage == 'in_transit' &&
  				transferOrder.transfer_order.to_stockroom.type.value == 'field_agent')
  			return true;
  		else if (transferOrder.stage == 'received' &&
  				transferOrder.quantity_received > transferOrder.quantity_returned)
  			return true;
  		else
  			return false;
  		
  	} else if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.field_service_management') &&
  			requestedUIAction == 'delivered' &&
  			!transferOrder.transfer_order.service_order.nil() &&
  			!transferOrder.transfer_order.service_order.assigned_to.nil() &&
  			transferOrder.transfer_order.service_order.state != 16) {
  		if (transferOrder.stage == 'in_transit' &&
  				transferOrder.transfer_order.to_stockroom.type.value == 'field_agent')
  			return true;
  		else if (transferOrder.stage == 'received' &&
  				transferOrder.quantity_received > transferOrder.quantity_returned)
  			return true;
  		else
  			return false;
  	} else
  		return false;
  },

  /*
   * Determines if the receive button with no dialog should pop up or not
   */
  isReceivingAllowed : function(transferOrderLine) {
  	if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.work_management') &&
  			transferOrderLine.transfer_order.to_stockroom.type.value == 'field_agent') {
  		return false;
  	} else if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.field_service_management') &&
  			transferOrderLine.transfer_order.to_stockroom.type.value == 'field_agent') {
  		return false;
  	} else if (transferOrderLine.stage == 'in_transit' ||
          ((SNC.AssetMgmtUtil.isPluginRegistered('com.snc.work_management') || SNC.AssetMgmtUtil.isPluginRegistered('com.snc.field_service_management')) && transferOrderLine.stage == 'requested')) {
  		if (transferOrderLine.quantity_remaining == 1 || transferOrderLine.asset.substatus == 'pre_allocated')
  			return true;
  		else
  			return false;
  	}
  },

  /*
   * Determines if the receive button with dialog should pop up or not
   */
  isReceivingAllowedDialog : function(transferOrderLine) {
  	if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.work_management') &&
  			transferOrderLine.transfer_order.to_stockroom.type.value == 'field_agent') {
  		return false;
  	} else if (SNC.AssetMgmtUtil.isPluginRegistered('com.snc.field_service_management') &&
  			transferOrderLine.transfer_order.to_stockroom.type.value == 'field_agent') {
  		return false;
  	} else if (transferOrderLine.stage == 'in_transit') {
  		if (transferOrderLine.quantity_remaining != 1 &&
  				(transferOrderLine.model.sys_class_name == 'cmdb_consumable_product_model' || transferOrderLine.model.asset_tracking_strategy == 'track_as_consumable'))
  			return true;
  		else
  			return false;
  	}
  },

  /*
   * Propagates the Transfer Order Stages among its Transfer Order Line Stages
   */
  pushStageFromTO : function(transferOrder, action) {
  	var newTOLStage = 0;
  	var newTOStage = 0;
  	if (action == 'requested') {
  		newTOLStage = 1;
  		newTOStage = 1;
  	} else if (action == 'shipment_preparation') {
  		newTOLStage = 2;
  		newTOStage = 2;
  		if (transferOrder.stage == 'partially_shipped')
  			newTOStage = 3;
  	} else if (action == 'ship') {
  		newTOLStage = 3;
  		newTOStage = 4;
  	}

  	var helper = new TransferOrderStageHelper();
  	var grTOL = new GlideRecord('alm_transfer_order_line');
  	grTOL.addQuery('transfer_order', transferOrder.sys_id);
  	grTOL.addQuery('stage', helper.getStageTOL(newTOLStage - 1).stage);
  	grTOL.query();

  	while (grTOL.next()) {
  		grTOL.stage = helper.getStageTOL(newTOLStage).stage;
  		if (action == 'requested')
  			grTOL.quantity_remaining = grTOL.quantity_requested;
  		grTOL.update();
  	}

  	transferOrder.stage = helper.getStageTO(newTOStage).stage;
  	transferOrder.update();
  },

  /*
   * When all the Transfer Order Lines change to specific stages, it pushes
   * the Transfer Order to change its stage
   */
  pushStageFromTOL : function(transferOrderLine, action) {
  	var totalChildren = parseInt(this._getChildrenCount(transferOrderLine.transfer_order));
  	var stageChildren = parseInt(this._getChildrenInStage(transferOrderLine.transfer_order, transferOrderLine.stage));

  	var closedTasks = parseInt(this._getClosedInStageTaskCount(transferOrderLine.transfer_order, transferOrderLine.stage));
  	var totalTasks = parseInt(this._getTotalInStageTaskCount(transferOrderLine.transfer_order, transferOrderLine.stage));
  	
  	var totalPresentFutureTasks = parseInt(this._getTotalTaskCountForAModelCategory(transferOrderLine.transfer_order, transferOrderLine.stage));
  	
  	var grTO = new GlideRecord('alm_transfer_order');
  	grTO.addQuery('sys_id', transferOrderLine.transfer_order.sys_id);
  	grTO.query();

  	if (grTO.next()) {
  		if (action === 'requested' && closedTasks === 1){
  			grTO.stage = action;
  		} else if (action === 'in_transit') {
  			if ((totalPresentFutureTasks === closedTasks) || totalChildren === stageChildren)
  				grTO.stage = 'fully_shipped';
  			else
  				grTO.stage = 'partially_shipped';
  		} else if (action === 'cancelled') {
  			if (totalChildren === stageChildren) {
  				grTO.stage = 'cancelled';
  			} else {
  				this._checkTOStateChangeOnTOLCancellation(transferOrderLine.transfer_order);
  			}
  		} else if ((action === 'received' || action === 'delivered') &&
  				((totalPresentFutureTasks === closedTasks) || totalChildren === stageChildren))
  			grTO.stage = action;
  		else if (action === 'shipment_preparation' &&
  				grTO.getValue('stage') !== 'partially_shipped')
  			grTO.stage = action;
  		grTO.update();
  		
  		if (action === 'requested'){
  			var grTOL = new GlideRecord('alm_transfer_order_line');
  			grTOL.addQuery('sys_id', transferOrderLine.sys_id);
  			grTOL.query();
  			if(grTOL.next()){
  				grTOL.quantity_remaining = grTOL.quantity_requested;
  				grTOL.update();
  			}
  		}
  	}
  },

  _checkTOStateChangeOnTOLCancellation: function (transferOrder) {
  	// If transfer order has stage partially_shipped, check on cancellation of TOL,
  	// if the stage needs to be changed to fully_shipped, received or delivered.
  	var transferOrderStage = String(transferOrder.stage);
  	if (transferOrderStage !== 'partially_shipped') { return; }
  	
  	var stage;
  	var grTO = new GlideRecord('alm_transfer_order');
  	var transferOrderID = String(transferOrder.sys_id);
  	
  	// Checking if transfer order stage should be changed to Delivered.
  	stage = 'delivered'; // action = 'delivered';
  	if (this._shouldChangeTransferOrderStageBasedOnTasksAndTOL(transferOrder, stage)) {
  		setTransferOrderStage(grTO, transferOrderID, 'fully_shipped');
  		setTransferOrderStage(grTO, transferOrderID, 'received');
  		setTransferOrderStage(grTO, transferOrderID, 'delivered');
  		return;
  	}
  	
  	// Checking if transfer order stage should be changed to Received
  	stage = 'received'; // action = 'received';
  	if (this._shouldChangeTransferOrderStageBasedOnTasksAndTOL(transferOrder, stage)) {
  		setTransferOrderStage(grTO, transferOrderID, 'fully_shipped');
  		setTransferOrderStage(grTO, transferOrderID, 'received');
  		return;
  	}
  	
  	// Checking if transfer order stage should be changed to Fully Shipped
  	stage = 'in_transit'; // action = 'in_transit';
  	if (this._shouldChangeTransferOrderStageBasedOnTasksAndTOL(transferOrder, stage)) {
  		setTransferOrderStage(grTO, transferOrderID, 'fully_shipped');
  		return;
  	}
  	
  	function setTransferOrderStage (grTO, sysID, stage) {
  		grTO.initialize();
  		grTO.get(sysID);
  		grTO.setValue('stage', stage);
  		grTO.update();
  	}
  },
  
  _shouldChangeTransferOrderStageBasedOnTasksAndTOL: function (transferOrder, stage) {
  	var stageChildren = parseInt(this._getChildrenInStage(transferOrder, stage));
  	if (stageChildren > 0) {
  		var totalChildren = parseInt(this._getChildrenCount(transferOrder));
  		var closedTasks = parseInt(this._getClosedInStageTaskCount(transferOrder, stage));
  		var totalPresentFutureTasks = parseInt(this._getTotalTaskCountForAModelCategory(transferOrder, stage));
  		
  		if ((totalPresentFutureTasks === closedTasks) || totalChildren === stageChildren) {
  			return true;
  		}
  	}
  	return false;
  },
  
  _getTotalTaskCountForAModelCategory: function(transferOrder, stage){
  	var grTOLTask = new GlideRecord('alm_transfer_order_line');
  	grTOLTask.addQuery('transfer_order', transferOrder);
  	grTOLTask.addQuery('stage', 'NOT IN', 'cancelled');
  	grTOLTask.query();
  	// For each TOL in TO
  	var totalTaskcount = 0;
  	while(grTOLTask.next()){
  		var templateTaskGr = new GlideRecord('alm_template_task');
  		templateTaskGr.addQuery('model_category', grTOLTask.asset.model_category);
  		templateTaskGr.query();
  		if(!templateTaskGr.hasNext()){
  			var defaultTemplateTaskGr = this._getGr(TransferOrderLineTemplateTaskAPI.DEFAULT_MODEL_CATEGORY, stage);
  			if(defaultTemplateTaskGr.next()){
  				totalTaskcount = totalTaskcount + parseInt(defaultTemplateTaskGr.getAggregate('COUNT'));
  			}
  		}else {
  			var definedTemplateTaskGr = this._getGr(grTOLTask.asset.model_category, stage);
  			if(definedTemplateTaskGr.next()){
  				totalTaskcount = totalTaskcount + parseInt(definedTemplateTaskGr.getAggregate('COUNT'));
  			}
  		}
  	}
  	return totalTaskcount;
  },
  
  _getTotalInStageTaskCount: function (transferOrder, stage){
  	var totalInStageTaskCount = 0;
  	var grTOLTask = new GlideAggregate('alm_transfer_order_line_task');
  	grTOLTask.addQuery('transfer_order_line.transfer_order', transferOrder);
  	grTOLTask.addQuery('stage', 'IN', stage);
  	grTOLTask.addAggregate('COUNT');
  	grTOLTask.query();
  	if(grTOLTask.next()){
  		totalInStageTaskCount = grTOLTask.getAggregate('COUNT');
  	}
  	return totalInStageTaskCount;
  },
  
  _getClosedInStageTaskCount : function(transferOrder, stage){
  	var closedInStageTaskCount = 0;
  	var grTOLTask = new GlideAggregate('alm_transfer_order_line_task');
  	grTOLTask.addQuery('transfer_order_line.transfer_order', transferOrder);
  	grTOLTask.addQuery('transfer_order_line.stage', 'NOT IN', 'cancelled');
  	grTOLTask.addQuery('stage', 'IN', stage);
  	// State = 3 = Closed Complete, State = 7 = Closed Skipped
  	grTOLTask.addQuery('state', 'IN', '3,7');
  	grTOLTask.addAggregate('COUNT');
  	grTOLTask.query();
  	if(grTOLTask.next()){
  		closedInStageTaskCount = grTOLTask.getAggregate('COUNT');
  	}
  	return closedInStageTaskCount;
  },
  
  _getGr : function(modelCategorySysId, stage) {
  	var templateTaskGr = new GlideAggregate('alm_template_task');
  	templateTaskGr.addQuery('model_category', modelCategorySysId);
  	templateTaskGr.addQuery('stage', stage);
  	templateTaskGr.addAggregate('COUNT');
  	templateTaskGr.query();
  	return templateTaskGr;
  },

  _getChildrenInStage : function(transferOrder, stage) {
  	var grTOL = new GlideRecord('alm_transfer_order_line');
  	grTOL.addQuery('transfer_order', transferOrder.sys_id);
  	grTOL.addQuery('stage', 'IN', stage);
  	grTOL.query();

  	return grTOL.getRowCount();
  },

  _getChildrenCount : function(transferOrder) {
  	var grTOL = new GlideRecord('alm_transfer_order_line');
  	grTOL.addQuery('transfer_order', transferOrder.sys_id);
  	grTOL.query();

  	return grTOL.getRowCount();
  },

  type : 'TransferOrderStageHandler'
};

Sys ID

99549fb8c32310007304072a1fba8fea

Offical Documentation

Official Docs: