"Invalid Update" error message. I had a requirement to add a new state "DCAB" to Normal Change right after the OOB "scheduled" state.

Dead Blade
Kilo Guru

I had a requirement to add a new state "DCAB" to Normal Change right after the OOB "scheduled" state.  You would think this is straight forward but I keep getting the "Invalid Update" error message.  Of course like other posts I can deactivate the BR "State model - Can change state?"

"Help me Obi Wan Kenobi, you're my only hope"

I have attached the Script Includes:

1.  ChangeRequestStateHandler

 

var ChangeRequestStateHandler = Class.create();

// All references to statehandler constants should be through this class ChangeRequestStateHandler
ChangeRequestStateHandler.DRAFT = ChangeRequestStateHandlerSNC.DRAFT;  
ChangeRequestStateHandler.NEW = ChangeRequestStateHandlerSNC.NEW;
ChangeRequestStateHandler.ASSESS = ChangeRequestStateHandlerSNC.ASSESS;
ChangeRequestStateHandler.AUTHORIZE = ChangeRequestStateHandlerSNC.AUTHORIZE;
ChangeRequestStateHandler.SCHEDULED = ChangeRequestStateHandlerSNC.SCHEDULED;
ChangeRequestStateHandler.IMPLEMENT = ChangeRequestStateHandlerSNC.IMPLEMENT;
ChangeRequestStateHandler.REVIEW = ChangeRequestStateHandlerSNC.REVIEW;
ChangeRequestStateHandler.CLOSED = ChangeRequestStateHandlerSNC.CLOSED;
ChangeRequestStateHandler.CANCELED = ChangeRequestStateHandlerSNC.CANCELED;
ChangeRequestStateHandler.DCAB = "dcab";  // New State

ChangeRequestStateHandler.prototype = Object.extendsObject(ChangeRequestStateHandlerSNC, {
    initialize: function(changeRequestGr) {
        ChangeRequestStateHandlerSNC.prototype.initialize.call(this, changeRequestGr);
        this.STATE_NAMES[30] = ChangeRequestStateHandler.DCAB;  // Added State
    },

    type: "ChangeRequestStateHandler"
});

 

2.  ChangeRequestStateModel_normal

Description

This script include represents the state model for normal changes. The script include ChangeRequestStateHandler controls the transitioning between states using this model to determine what transitions are allowed.

The script include 'ChangeRequestStateModelSNC_normal', which this one extends, contains the implementation for all the 'moving' and 'canMove' functions.

Model structure using the first property "draft":
    draft - current state the change request is in
    nextState - the state the change request can move to without specifying a state
    assess - a state the change request can move to when in draft if this.toAssess.canMove() returns true
                 - when the change request moves to assess, this.toAssess.moving() is called
    canceled - works in the exact same way that assess does

ChangeRequestStateHandler keeps a mapping of these friendly state names with their respective numeric value:
STATE_NAMES: {
        "-5": "draft",
        "-4": "assess",
        "-3": "authorize",
        "-2": "scheduled",
        "30": "dcab",
        "-1": "implement",
        "0": "review",
        "3": "closed",
        "4": "canceled"
}

 

Script

var ChangeRequestStateModel_normal = Class.create();
ChangeRequestStateModel_normal.prototype = Object.extendsObject(ChangeRequestStateModelSNC_normal, {
    draft: {
        nextState: [ "assess" ],

        assess: {
            moving: function() {
                return this.toAssess_moving();
            },

            canMove: function() {
                return this.toAssess_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },

    assess: {
        nextState: [ "authorize" ],

        draft: {
            moving: function() {
                return this.toDraft_moving();
            },

            canMove: function() {
                return this.toDraft_canMove();
            }
        },

        authorize: {
            moving: function() {
                return this.toAuthorize_moving();
            },

            canMove: function() {
                return this.toAuthorize_canMove();
            }
        },

        scheduled: {
            moving: function() {
                return this.toScheduled_moving();
            },

            canMove: function() {
                return this.toScheduled_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },

    authorize: {
        nextState: [ "scheduled" ],

        scheduled: {
            moving: function() {
                return this.toScheduled_moving();
            },

            canMove: function() {
                return this.toScheduled_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },

    scheduled: {
        nextState: [ "dcab" ],
        
        draft: {
            moving: function() {
                return this.toDraft_moving();
            },

            canMove: function() {
                return this.toDraft_canMove();
            }
        },

        dcab: {
            moving: function() {
                return this.toDcab_moving();
            },
            canMove: function() {
                return this.toDcab_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },
    
    dcab: {
        nextState: [ "implement" ],
        draft: {
            moving: function() {
                return this.toDraft_moving();
            },

            canMove: function() {
                return this.toDraft_canMove();
            }
        },

        implement: {
            moving: function() {
                return this.toImplement_moving();
            },
            canMove: function() {
                return this.toImplement_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },
    implement: {
        nextState: [ "review" ],

        review: {
            moving: function() {
                return this.toReview_moving();
            },

            canMove: function() {
                return this.toReview_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },

    review: {
        nextState: [ "closed" ],

        closed: {
            moving: function() {
                return this.toClosed_moving();
            },

            canMove: function() {
                return this.toClosed_canMove();
            }
        },

        canceled: {
            moving: function() {
                return this.toCanceled_moving();
            },

            canMove: function() {
                return this.toCanceled_canMove();
            }
        }
    },

    closed: {},

    canceled: {},
    
    // dcab:  {},

    type: "ChangeRequestStateModel_normal"
});

1 ACCEPTED SOLUTION

I figured it out, my script include "ChangeRequestStateModel_normal " was missing the last few lines:

 

Update the state model script include

Procedure

  1. Navigate to System Definition > Script Includes.
  2. Open the ChangeRequestStateModel_normal script include and modify the script as follows.
    1. Add the following line at the end of the script include but before the line that starts with type:
      toComplete_moving: function() {
                    return true; 
               },              
      
               toComplete_canMove: function() {      
                     return true;       
               },

View solution in original post

4 REPLIES 4

Michael Fry1
Kilo Patron

The scripts you posted all look fine. Did you do all of these steps: https://docs.servicenow.com/bundle/kingston-it-service-management/page/product/change-management/tas...

Do you have any other advice to look for?

Dead Blade
Kilo Guru

Hi Michael, I didn't

The New State is only for another change board approval state so there will NOT be a new field on the form.  The idea is, after the scheduled state the CHANGE will move to DCAB if blah blah blah, if not it will bypass and go to Implement.  So all I really want is a new State that will have approvals reflected in approvals if required.  Make sense?

 

I figured it out, my script include "ChangeRequestStateModel_normal " was missing the last few lines:

 

Update the state model script include

Procedure

  1. Navigate to System Definition > Script Includes.
  2. Open the ChangeRequestStateModel_normal script include and modify the script as follows.
    1. Add the following line at the end of the script include but before the line that starts with type:
      toComplete_moving: function() {
                    return true; 
               },              
      
               toComplete_canMove: function() {      
                     return true;       
               },