Project state / Project task state

Susan Davidson
Giga Guru

We have a need for when project tasks (all those active) are placed on hold then the parent project also sets to onhold
The current plannedtaskstateutil sets it to Work In Progress instead if there is one or more closed tasks.
So if in this example We have 3 tasks on hold and one in closed complete the parent task is defaulting to Work In Progress - it should instead ignore the closed complete task in this case and show the parent task as ON HOLD (state 5) as all active tasks are on hold.
It should only pay attention to the closed complete when ALL tasks are closed complete.

I attempted to update the plannedtaskstateutil to achieve this but it is still not working.
If all tasks are placed in ON hold that DOES now work and set the parent on hold also but as soon as one task is in closed it ignores that rule.
How do we modify this/achieve this requirement; this is my current util script

/*
 * Planned Task State Management Utility
 * primarily used by the Task Active State Management business rule to set the active
 * field based on state changes
 * Can be called by any server script to determine inactive states, default work, or default
 * close states for a given table
 */

/*
 * Usage:
 * var stateUtil = new PlannedTaskStateUtil(current);
 * var openState = stateUtil.getDefaultOpenState();
 * var skippedState = stateUtil.getDefaultSkippedState();
 */

var PlannedTaskStateUtil = Class.create();

PlannedTaskStateUtil.PENDING_STATES = "pending_states";
PlannedTaskStateUtil.OPEN_STATES = "open_states";
PlannedTaskStateUtil.WORK_IN_PROGRESS = "work_in_progress_states";
PlannedTaskStateUtil.CLOSE_STATES = "close_states";
PlannedTaskStateUtil.SKIPPED_STATES = "skipped_states";
PlannedTaskStateUtil.ONHOLD_STATES = "onhold_states";

PlannedTaskStateUtil.prototype = {
   
    /*
    * static properties and default values
    */
    ATTR_DEFAULT_OPEN : "default_open_state",
    ATTR_DEFAULT_SKIPPED : "default_skipped_state",
    ATTR_DEFAULT_PENDING : "default_pending_state",
    ATTR_DEFAULT_WORK : "default_work_state",
    ATTR_DEFAULT_CLOSE : "default_close_state",
    ATTR_DEFAULT_ONHOLD : "default_onhold_state",
    SYSTEM_DEFAULT_OPEN : 1// task closed complete state
    SYSTEM_DEFAULT_SKIPPED : 7// task closed skipped state
    SYSTEM_DEFAULT_PENDING : -5,    //task pending state
    SYSTEM_DEFAULT_WORK : 2// task work in progress state
    SYSTEM_PENDING_STATES : [-5],   //as of now only one pending state, user can override in dictionary if more pending states are required.
    SYSTEM_OPEN_STATES   : [1],
    SYSTEM_WORK_IN_PROGRESS : [2],
    SYSTEM_CLOSE_STATES : [3,4,7],
    SYSTEM_ONHOLD_STATES : [5],
   
    /*
    * Init
    * called by new PlannedTaskStateUtil(gr)
    * @Param task GlideRecord
    */
    initialize : function(/*GlideRecord*/ task) {
       
        if (!task)
            return;
        var sysClassName;
        if(task.sys_class_name){
            sysClassName = task.sys_class_name;
        }else{
            sysClassName = task.getTableName();
        }
        var taskRec = new GlideRecord(sysClassName);
        taskRec.initialize();
        this.task = taskRec;
        this.stateBuckets = {};
        this.stateElement = this.task.state;
        this.stateAttributeExists = false// default to false
       
       
        // get optional attributes or use default values
        this._getDefaultOpen();
        this._getDefaultSkipped();
        this._getDefaultPending();
        this._getDefaultWorkState();
        this._getDefaultClose();
        this._getdefaultOnholdState();
        this._getPendingStates();
        this._getOpenStates();
        this._getWorkInProgressStates();
        this._getCloseStates();
        this._getSkippedStates();
        this._getOnholdStates();
        this._populateStateBuckets();
    },

    getDefaultState: function(table) {
        var tableDescriptor = new GlideTableDescriptor(table);
        var elementDescriptor = tableDescriptor.getElementDescriptor('state');
        var defaultState = elementDescriptor.getDefault();
        return defaultState? defaultState : this.getDefaultPendingState();
    },
   
    /*
    * Get the value for the default work state, defaults to 1 if not specified
    * @return int
    */
    getDefaultOpenState : function() {
        return this.defaultOpen;
    },
   
    /*
    * Get the value for the default close state, defaults to 3 if not specified
    * @return int
    */
    getDefaultSkippedState : function() {
        return this.defaultSkipped;
    },
   
    /*
    * Get the value for the default pending state, defaults to -5 if not specified
    * @return int
    */
    getDefaultPendingState : function() {
        return this.defaultPending;
    },
   
    getDefaultWorkState : function() {
        return this.defaultWork;
    },
   
    getDefaultCloseState : function() {
        return this.defaultClose;
    },
    getDefaultOnholdState : function() {
        return this.defaultOnhold;
    },
   
    getPendingStates : function() {
        return this.pendingStates;
    },
   
    getOpenStates : function() {
        return this.openStates;
    },
   
    getWorkInProgressStates : function() {
        return this.workInProgressStates;
    },
   
    getCloseStates : function() {
        return this.closeStates;
    },

    getSkippedStates: function() {
        return this.skippedStates;
    },
    getOnholdStates: function() {
        return this.onholdStates;
    },
   
     /*
    * Get the active status of a given state
    * @Param state value of the state field choice
    * @return boolean true if state is an active state
    */
   isStateInactive : function(state) {
      state = state + "";
      var arrUtil = new ArrayUtil();
      if (arrUtil.contains(this.closeStates, state))
         return true;
     
      return false;
   },
   
   
    isStateOpen : function(state) {
        state = state + "";
        var arrUtil = new ArrayUtil();
        if (arrUtil.contains(this.openStates, state))
            return true;
       
        return false;
    },
    isStateOnhold : function(state) {
        state = state + "";
        var arrUtil = new ArrayUtil();
        if (arrUtil.contains(this.onholdStates, state))
            return true;
       
        return false;
    },
    isStateWIP : function(state) {
        state = state + "";
        var arrUtil = new ArrayUtil();
        if (arrUtil.contains(this.workInProgressStates, state))
            return true;
       
        return false;
    },
   
    isStatePending : function(state) {
        state = state + "";
        var arrUtil = new ArrayUtil();
        if (arrUtil.contains(this.pendingStates, state))
            return true;
       
        return false;
    },
   
    //private methods used in init()
    _getDefaultOpen : function() {
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_OPEN);
        if (value)
            this.defaultOpen = value;
        else
            this.defaultOpen = this.SYSTEM_DEFAULT_OPEN;
    },
   
    _getDefaultSkipped : function() {
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_SKIPPED);
        if (value)
            this.defaultSkipped = value;
        else
            this.defaultSkipped = this.SYSTEM_DEFAULT_SKIPPED;
    },
    _getDefaultOnhold : function() {
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_ONHOLD);
        if (value)
            this.defaultOnhold = value;
        else
            this.defaultOnhold = this.SYSTEM_DEFAULT_ONHOLD;
    },  
    _getDefaultPending : function() {
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_PENDING);
        if (value)
            this.defaultPending = value;
        else
            this.defaultPending = this.SYSTEM_DEFAULT_PENDING;
    },
   
    _getDefaultWorkState: function() {
        // See if a value exists for the default work state attribute
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_WORK);
       
        if (value)
            this.defaultWork = value;
        else
            this.defaultWork = this.SYSTEM_DEFAULT_WORK;
    },
   
    _getDefaultClose : function() {
        var value = this.stateElement.getAttribute(this.ATTR_DEFAULT_CLOSE);
        if (value)
            this.defaultClose = value;
        else
            this.defaultClose = this.SYSTEM_DEFAULT_CLOSE;
    },
   
    _getPendingStates : function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.PENDING_STATES);
        if(attribute){
            var states = attribute.split(";");
            this.pendingStates = states;
        }
        else {
            this.pendingStates = this.SYSTEM_PENDING_STATES;
        }
    },
    _getOnholdStates : function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.ONHOLD_STATES);
        if(attribute){
            var states = attribute.split(";");
            this.OnholdStates = states;
        }
        else {
            this.OnholdStates = this.SYSTEM_ONHOLD_STATES;
        }
    },  
    _getOpenStates : function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.OPEN_STATES);
        if(attribute){
            var states = attribute.split(";");
            this.openStates = states;
        }
        else {
            this.openStates = this.SYSTEM_OPEN_STATES;
        }
    },
   
    _getWorkInProgressStates : function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.WORK_IN_PROGRESS);
        if(attribute){
            var states = attribute.split(";");
            this.workInProgressStates = states;
        }
        else {
            this.workInProgressStates = this.SYSTEM_WORK_IN_PROGRESS;
        }
       
    },
   
    _getCloseStates : function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.CLOSE_STATES);
        if(attribute){
            var states = attribute.split(";");
            this.closeStates = states;
        }
        else {
            this.closeStates = this.SYSTEM_CLOSE_STATES;
        }
    },

    _getSkippedStates: function() {
        var attribute = this.stateElement.getAttribute(PlannedTaskStateUtil.SKIPPED_STATES);
        this.skippedStates = [];
        if(!JSUtil.nil(attribute)){
            var states = attribute.split(";");
            this.skippedStates = states;
        }
    },
   
    _populateStateBuckets : function() {
        var state;
       
        for(var index in this.pendingStates){
            state = this.pendingStates[index];
            this.stateBuckets[state] = PlannedTaskStateUtil.PENDING_STATES;
        }
        for(var index in this.onholdStates){
            state = this.onholdStates[index];
            this.stateBuckets[state] = PlannedTaskStateUtil.ONHOLD_STATES;
        }
        for(index in this.openStates){
            state = this.openStates[index];
            this.stateBuckets[state] = PlannedTaskStateUtil.OPEN_STATES;
        }
        for(index in this.workInProgressStates){
            state = this.workInProgressStates[index];
            this.stateBuckets[state] = PlannedTaskStateUtil.WORK_IN_PROGRESS;
        }
        for(index in this.closeStates){
            state = this.closeStates[index];
            this.stateBuckets[state] = PlannedTaskStateUtil.CLOSE_STATES;
        }
    },
   
    getBucketForState : function(state) {
        if(this.stateBuckets.hasOwnProperty(state)){
            return this.stateBuckets[state];
        }
        return null;
    },
   
    isValidState : function(bucketName, state) {
        if(this.stateBuckets.hasOwnProperty(state)){
            var cl = GlideSysChoice(this.task.getTableName(),'state');
            var stateChoices = cl.getChoices();
            var choice;
            while(stateChoices.next()){
                choice = stateChoices.getValue('value');
                if(choice == state){
                    return (this.stateBuckets[state] == bucketName) ? true : false;
                }
            }
        }
        return false;
    },
   
    getDefaultStateForBucket : function(bucketName){
        if(bucketName == PlannedTaskStateUtil.PENDING_STATES)
            return this.getDefaultPendingState();
        else if(bucketName == PlannedTaskStateUtil.OPEN_STATES)
            return this.getDefaultOpenState();
        else if(bucketName == PlannedTaskStateUtil.WORK_IN_PROGRESS)
            return this.getDefaultWorkState();
        else if(bucketName == PlannedTaskStateUtil.CLOSE_STATES)
            return this.getDefaultCloseState();
        else if(bucketName == PlannedTaskStateUtil.ONHOLD_STATES)
            return this.getDefaultOnholdState();
        else
            return null;
    },
   
    getValidStateForBucket : function(bucket, state) {
        if (this.isValidState(bucket, state)) {
            return state;
        } else {
            var defaultState = this.getDefaultStateForBucket(bucket);
            return defaultState;
        }
    },
   
    getStateBuckets: function() {
        return this.stateBuckets;
    },
   
    type : "PlannedTaskStateUtil"
};
0 REPLIES 0