Change Order Sample Code

Any many of you have pointed out, there isn't much sample code out there on working with Change Orders.  So let me attempt to remedy that by providing code on two common operations you might want to do through the API:  creating a new Change Order and updating the lifecycle state of a Change Order.

Adding a new Change Order
A new Change Order will always use the default workflow.  A workflow is the set of lifecycle states and transitions (activities) between them.  Once created, the Change Order is locked to that workflow forever. 

So, when you create a new Change Order you don't need to pass in the workflow.  But you do need to pass in the routing, which is the set of users and their roles on that Change Order.  You also need to pass in the number for the Change Order.  The easiest route is to just use the default routing and default numbering scheme, as shown below.

// C#
private void NewChangeOrder(ChangeOrderService coSvc)
{
    // get the default routing
    Workflow workflow = coSvc.GetDefaultWorkflow();
    Routing [] routings = coSvc.GetRoutingsByWorkflowId(workflow.Id);
    Routing defaultRouting = routings.FirstOrDefault(n => n.IsDflt);
    if (defaultRouting == null)
        throw new Exception("No default routing");

    // get the next number in the default sequence
    ChangeOrderNumSchm [] numberingSchemes = 
        coSvc.GetNumberingSchemesByType(NumSchmType.ApplicationDefault);
    ChangeOrderNumSchm defaultNumberingScheme = numberingSchemes.FirstOrDefault();
    if (defaultNumberingScheme == null)
        throw new Exception("No default numbering scheme");
    string coNumber = coSvc.GetChangeOrderNumberBySchemeId(defaultNumberingScheme.Id);

    // create the new change order
    ChangeOrder newCo = coSvc.AddChangeOrder(defaultRouting.Id, coNumber, "Sample CO", "Sample", DateTime.Now.AddMonths(1), null, null, null, null, null, null, null);
}

' VB.NET
Private Sub NewChangeOrder(coSvc As ChangeOrderService)
       ' get the default routing
       Dim workflow As Workflow = coSvc.GetDefaultWorkflow()
       Dim routings As Routing() = coSvc.GetRoutingsByWorkflowId(workflow.Id)
       Dim defaultRouting As Routing = routings.FirstOrDefault(Function(n) n.IsDflt)
       If defaultRouting Is Nothing Then
              Throw New Exception("No default routing")
       End If

       ' get the next number in the default sequence
       Dim numberingSchemes As ChangeOrderNumSchm() = _
           coSvc.GetNumberingSchemesByType(NumSchmType.ApplicationDefault)
       Dim defaultNumberingScheme As ChangeOrderNumSchm = _
           numberingSchemes.FirstOrDefault()
       If defaultNumberingScheme Is Nothing Then
              Throw New Exception("No default numbering scheme")
       End If
       Dim coNumber As String = coSvc.GetChangeOrderNumberBySchemeId( _
           defaultNumberingScheme.Id)

       ' create the new change order
       Dim newCo As ChangeOrder = coSvc.AddChangeOrder( _
        defaultRouting.Id, coNumber, "Sample CO", "Sample", _ 
           DateTime.Now.AddMonths(1), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
End Sub

 

Moving to a new state
One nice thing is that the Change Order object has an Activities property which lists all the valid state changes currently possible.  So, all your code needs to do is pick one and run the update calls.  There are a few things you need to know:

  • There might not be any activities.  There are a couple of "sink" states where Change Orders cannot move out of.
  • An activity might loop back to the same state.  For example, you can perform the review operation when you are in the review state.  This will result in the Change Order moving to the review state.  So even though an activity was performed, the state is the same.
  • Closing a Change Order requires additional information, effectivity.  Therefore, a different API function is used for that case.

Like with many Item operations, you need to do 2 calls to perform the update.  The first call starts the operation and the second call commits the operation.  If something goes wrong, you need to call an undo function.

private void ChangeState(ChangeOrderService coSvc, ChangeOrder co)
{
    if (co.ActivityArray == null || co.ActivityArray.Length == 0)
        throw new Exception("Change Order cannot be moved to another state");
    // for demo purposes, we will just pick the first one
    Activity activity = co.ActivityArray[0];
    ChangeOrder editableCo = null;
    try
    {
        editableCo = coSvc.StartChangeOrderActivity(
            co.Id, activity.Id, co.StateId, co.StateEntered);
        ChangeOrder committedCo;
        if (activity.Name == "Set Effectivity")
        {
            committedCo = coSvc.CommitChangeOrderCloseActivity(
                editableCo.Id, activity.Id, editableCo.StateId,
                editableCo.StateEntered, null, null,
                DateTime.Now, DateTime.MaxValue);
        }
        else
        {
            committedCo = coSvc.CommitChangeOrderActivity(
                editableCo.Id, activity.Id, editableCo.StateId,
                editableCo.StateEntered, null, null);
        }
    }
    catch
    {
        if (editableCo != null)
            coSvc.CancelChangeOrderActivity(editableCo.Id, activity.Id);
        throw;
    }
}

Private Sub ChangeState(coSvc As ChangeOrderService, co As ChangeOrder)
       If co.ActivityArray Is Nothing OrElse co.ActivityArray.Length = 0 Then
              Throw New Exception("Change Order cannot be moved to another state")
       End If

       ' for demo purposes, we will just pick the first one
       Dim activity As Activity = co.ActivityArray(0)

       Dim editableCo As ChangeOrder = Nothing
       Try
              editableCo = coSvc.StartChangeOrderActivity( _
                  co.Id, activity.Id, co.StateId, co.StateEntered)
              Dim committedCo As ChangeOrder
              If activity.Name = "Set Effectivity" Then
                     committedCo = coSvc.CommitChangeOrderCloseActivity( editableCo.Id, activity.Id, editableCo.StateId, editableCo.StateEntered, Nothing, Nothing, DateTime.Now, DateTime.MaxValue)
              Else
                     committedCo = coSvc.CommitChangeOrderActivity( editableCo.Id, activity.Id, editableCo.StateId, editableCo.StateEntered, Nothing, Nothing)
              End If
       Catch
              If editableCo IsNot Nothing Then
                     coSvc.CancelChangeOrderActivity(editableCo.Id, activity.Id)
              End If
              Throw
       End Try
End Sub


Comments

One response to “Change Order Sample Code”

  1. Hi,
    I am looking for some help regarding the Vault 2014 API to have an event triggered when an ECO item is at review state and the user clicks the approve option from the actions menu. What I am looking for is a Vault API call to catch this event and do some function there after.
    What event handler should I use from the 2014 API?
    Many thanks.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading