refactor[TW16754]: Move TransitionToOperation to server

Change-Id: Ib5972f299d0d9c245491d9d01aa6cec8b691d8bc
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/model/StateDefinition.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/model/StateDefinition.java
index 6bed8bb..177e030 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/model/StateDefinition.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/model/StateDefinition.java
@@ -91,7 +91,7 @@
 
    @Override
    public String toString() {
-      return String.format("[%s][%s]", getName(), getStateType());
+      return String.format("%s  - (%s)", getName(), getStateType());
    }
 
    /**
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/state/IAtsStateManager.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/state/IAtsStateManager.java
index 17c0af6..1f79e67 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/state/IAtsStateManager.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/state/IAtsStateManager.java
@@ -57,7 +57,7 @@
     */
    void setAssignees(String stateName, List<? extends AtsUser> assignees);
 
-   void transitionHelper(List<? extends AtsUser> toAssignees, IStateToken fromStateName, IStateToken toStateName, String cancelReason);
+   void transitionHelper(List<? extends AtsUser> toAssignees, IStateToken fromStateName, IStateToken toStateName);
 
    long getTimeInState();
 
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/ITransitionHelper.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/ITransitionHelper.java
index 462a47f..7c6fb3f 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/ITransitionHelper.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/ITransitionHelper.java
@@ -17,7 +17,6 @@
 import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
-import org.eclipse.osee.framework.core.util.Result;
 
 /**
  * @author Donald G. Dunne
@@ -31,19 +30,10 @@
    public Collection<IAtsWorkItem> getWorkItems();
 
    /**
-    * @return Result.isTrue with text if reason provided
-    * @return Result.isFalse if no reason given
-    * @return Result.isCancelled to cancel transition
+    * @return with cancellationReason and cancellationDetails set
+    * @return TransitionData.isDialogCancelled to cancel transition
     */
-   public Result getCompleteOrCancellationReason();
-
-   /**
-    * @param changes JavaTip
-    * @return Result.isTrue with text if hours provided
-    * @return Result.isFalse if no extra hours given
-    * @return Result.isCancelled to cancel transition
-    */
-   public Result handleExtraHoursSpent(IAtsChangeSet changes);
+   public TransitionData getCancellationReason(TransitionData transitionData);
 
    public Collection<? extends AtsUser> getToAssignees(IAtsWorkItem workItem);
 
@@ -81,4 +71,16 @@
 
    public void setAtsApi(AtsApi atsApi);
 
+   public String getCancellationReasonDetails();
+
+   public String getCancellationReason();
+
+   default void setCancellationReasonDetails(String cancelReasonDetails) {
+      // do nothing
+   }
+
+   default void setCancellationReason(String cancelReason) {
+      // do nothing
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionData.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionData.java
index 042a9d9..5e18951 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionData.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionData.java
@@ -23,6 +23,7 @@
 public class TransitionData {
 
    private String cancellationReason;
+   private String cancellationReasonDetails;
    private Collection<ArtifactToken> workItemIds = new HashSet<>();
    private String name;
    private Collection<TransitionOption> transitionOptions = new HashSet<>();
@@ -33,6 +34,7 @@
    private Collection<IAtsWorkItem> workItems = new HashSet<>();
    private AtsUser transitionUser;
    private boolean workflowsReloaded = false;
+   private boolean dialogCancelled = false;
 
    public TransitionData() {
       // for jax-rs
@@ -119,4 +121,20 @@
       this.transitionOptions = transitionOptions;
    }
 
+   public String getCancellationReasonDetails() {
+      return cancellationReasonDetails;
+   }
+
+   public void setCancellationReasonDetails(String cancellationReasonDetails) {
+      this.cancellationReasonDetails = cancellationReasonDetails;
+   }
+
+   public boolean isDialogCancelled() {
+      return dialogCancelled;
+   }
+
+   public void setDialogCancelled(boolean dialogCancelled) {
+      this.dialogCancelled = dialogCancelled;
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionResult.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionResult.java
index cc6222d..1536d42 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionResult.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionResult.java
@@ -11,7 +11,9 @@
 package org.eclipse.osee.ats.api.workflow.transition;
 
 import org.eclipse.osee.ats.api.workdef.ITransitionResult;
+import org.eclipse.osee.framework.jdk.core.type.OseeArgumentException;
 import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
 
 /**
  * @author Donald G. Dunne
@@ -46,7 +48,6 @@
       new TransitionResult("All Reviews must be cancelled before Cancelling Workflow.");
    public static TransitionResult TASKS_NOT_COMPLETED =
       new TransitionResult("Tasks Must be Completed/Cancelled to Transition");
-
    public static TransitionResult WORKITEM_DELETED =
       new TransitionResult("Work Item has been deleted.  Transition is invalid.");
 
@@ -58,6 +59,9 @@
    }
 
    public TransitionResult(String details, Exception ex) {
+      if (Strings.isInValid(details) && ex == null) {
+         throw new OseeArgumentException("Must have details or Exception");
+      }
       this.details = details;
       if (ex != null) {
          this.exception = Lib.exceptionToString(ex);
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionWorkItemResult.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionWorkItemResult.java
index 0fadec2..5cd9993 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionWorkItemResult.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/transition/TransitionWorkItemResult.java
@@ -69,14 +69,22 @@
       }
       StringBuffer sb = new StringBuffer();
       if (workItem != null) {
-         sb.append(workItem.getArtifactTypeName());
+         if (Strings.isValid(workItem.getArtifactTypeName())) {
+            sb.append(workItem.getArtifactTypeName());
+         } else {
+            sb.append("Work Item");
+         }
          sb.append(" [");
          sb.append(workItem.getAtsId());
          sb.append("] Titled [");
          sb.append(workItem.getName());
          sb.append("]\n\n");
       } else if (workItemId != null) {
-         sb.append(workItemId.getArtifactType().getName());
+         if (Strings.isValid(workItemId.getArtifactType().getName())) {
+            sb.append(workItemId.getArtifactType().getName());
+         } else {
+            sb.append("Work Item");
+         }
          sb.append(" [");
          sb.append(workItemId.getIdString());
          sb.append("] Titled [");
diff --git a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workdef/StateDefinitionTest.java b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workdef/StateDefinitionTest.java
index 607ebd2..dd24410 100644
--- a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workdef/StateDefinitionTest.java
+++ b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workdef/StateDefinitionTest.java
@@ -48,9 +48,9 @@
    @Test
    public void testToString() {
       StateDefinition def = new StateDefinition("endorse");
-      Assert.assertEquals("[endorse][null]", def.toString());
+      Assert.assertEquals("endorse  - (null)", def.toString());
       def.setStateType(StateType.Working);
-      Assert.assertEquals("[endorse][Working]", def.toString());
+      Assert.assertEquals("endorse  - (Working)", def.toString());
    }
 
    @Test
@@ -154,8 +154,7 @@
    @Test
    public void testGetWidgetsFromStateItems() {
       StateDefinition def = new StateDefinition("endorse");
-      Assert.assertEquals(0,
-         new AtsWorkDefinitionServiceImpl(atsApi, null).getWidgetsFromLayoutItems(def).size());
+      Assert.assertEquals(0, new AtsWorkDefinitionServiceImpl(atsApi, null).getWidgetsFromLayoutItems(def).size());
 
       IAtsWidgetDefinition widget1 = new WidgetDefinition("item 1");
       def.getLayoutItems().add(widget1);
@@ -173,8 +172,7 @@
       LayoutItem widget4 = new LayoutItem("item 4");
       stateItem3.getaLayoutItems().add(widget4);
 
-      Assert.assertEquals(3,
-         new AtsWorkDefinitionServiceImpl(atsApi, null).getWidgetsFromLayoutItems(def).size());
+      Assert.assertEquals(3, new AtsWorkDefinitionServiceImpl(atsApi, null).getWidgetsFromLayoutItems(def).size());
    }
 
    @Test
diff --git a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperAdapterTest.java b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperAdapterTest.java
index e7586ba..8cc26e4 100644
--- a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperAdapterTest.java
+++ b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperAdapterTest.java
@@ -24,7 +24,7 @@
 import org.eclipse.osee.ats.api.workflow.IAtsBranchService;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
 import org.eclipse.osee.ats.api.workflow.state.IAtsStateManager;
-import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -107,12 +107,7 @@
       }
 
       @Override
-      public Result getCompleteOrCancellationReason() {
-         return null;
-      }
-
-      @Override
-      public Result handleExtraHoursSpent(IAtsChangeSet changes) {
+      public TransitionData getCancellationReason(TransitionData transitionData) {
          return null;
       }
 
@@ -141,5 +136,15 @@
          return null;
       }
 
+      @Override
+      public String getCancellationReasonDetails() {
+         return null;
+      }
+
+      @Override
+      public String getCancellationReason() {
+         return null;
+      }
+
    }
 }
diff --git a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperTest.java b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperTest.java
index 0b73f4f..184cfa6 100644
--- a/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperTest.java
+++ b/plugins/org.eclipse.osee.ats.core.test/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelperTest.java
@@ -24,8 +24,8 @@
 import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
 import org.eclipse.osee.ats.api.workflow.IAtsWorkItemService;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
+import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionOption;
-import org.eclipse.osee.framework.core.util.Result;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -105,16 +105,16 @@
 
    @Test
    public void testGetCompleteOrCancellationReason() {
-      Result reason = helper.getCompleteOrCancellationReason();
-      Assert.assertEquals("cancel reason", reason.getText());
-      Assert.assertTrue(reason.isTrue());
+      TransitionData transitionData = new TransitionData();
+      transitionData.setCancellationReason("cancel reason");
+      helper.getCancellationReason(transitionData);
+      Assert.assertEquals("cancel reason", transitionData.getCancellationReason());
 
-      TransitionHelper helper2 = new TransitionHelper("test", Arrays.asList(workItem, workItem2), "Completed",
+      TransitionHelper transitionHelper = new TransitionHelper("test", Arrays.asList(workItem, workItem2), "Completed",
          Arrays.asList(Joe, Kay), null, changes, atsApi, TransitionOption.OverrideAssigneeCheck);
+      transitionHelper.setCancellationReason("cancel reason");
 
-      reason = helper2.getCompleteOrCancellationReason();
-      Assert.assertEquals("", reason.getText());
-      Assert.assertTrue(reason.isFalse());
+      transitionHelper.getCancellationReason(transitionData);
    }
 
    @Test
@@ -131,11 +131,6 @@
    }
 
    @Test
-   public void testHandleExtraHoursSpent() {
-      Assert.assertEquals(Result.TrueResult, helper.handleExtraHoursSpent(changes));
-   }
-
-   @Test
    public void testGetToStateName() {
       Assert.assertEquals("Completed", helper.getToStateName());
    }
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/state/StateManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/state/StateManager.java
index b83a5b8..0940534 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/state/StateManager.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/internal/state/StateManager.java
@@ -296,7 +296,7 @@
    }
 
    @Override
-   public void transitionHelper(List<? extends AtsUser> toAssignees, IStateToken fromState, IStateToken toState, String cancelReason) {
+   public void transitionHelper(List<? extends AtsUser> toAssignees, IStateToken fromState, IStateToken toState) {
       createState(toState);
       setAssignees(toState.getName(), toAssignees);
       setCurrentStateName(toState.getName());
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AtsWorkItemServiceImpl.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AtsWorkItemServiceImpl.java
index 57b445c..cae7eb1 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AtsWorkItemServiceImpl.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/AtsWorkItemServiceImpl.java
@@ -496,7 +496,8 @@
    @Override
    public TransitionResults transitionValidate(TransitionData transData) {
       TransitionHelper helper = new TransitionHelper(transData, null, atsApi);
-      TransitionResults results = transition(helper);
+      TransitionManager transitionMgr = new TransitionManager(helper);
+      TransitionResults results = transitionMgr.handleTransitionValidation(new TransitionResults());
       return results;
    }
 
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelper.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelper.java
index c50cd0e..883f351 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelper.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionHelper.java
@@ -20,9 +20,7 @@
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionOption;
-import org.eclipse.osee.framework.core.util.Result;
 import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
-import org.eclipse.osee.framework.jdk.core.util.Strings;
 import org.eclipse.osee.framework.logging.OseeLog;
 
 /**
@@ -79,11 +77,8 @@
    }
 
    @Override
-   public Result getCompleteOrCancellationReason() {
-      if (Strings.isValid(transData.getCancellationReason())) {
-         return new Result(true, transData.getCancellationReason());
-      }
-      return Result.FalseResult;
+   public TransitionData getCancellationReason(TransitionData transitionData) {
+      return transitionData;
    }
 
    @Override
@@ -97,11 +92,6 @@
    }
 
    @Override
-   public Result handleExtraHoursSpent(IAtsChangeSet changes) {
-      return Result.TrueResult;
-   }
-
-   @Override
    public String getToStateName() {
       return transData.getToStateName();
    }
@@ -171,4 +161,24 @@
       }
    }
 
+   @Override
+   public void setCancellationReasonDetails(String cancelReasonDetails) {
+      transData.setCancellationReasonDetails(cancelReasonDetails);
+   }
+
+   @Override
+   public void setCancellationReason(String cancelReason) {
+      transData.setCancellationReason(cancelReason);
+   }
+
+   @Override
+   public String getCancellationReasonDetails() {
+      return transData.getCancellationReasonDetails();
+   }
+
+   @Override
+   public String getCancellationReason() {
+      return transData.getCancellationReason();
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java
index 4f4c3e3..d163e1e 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workflow/transition/TransitionManager.java
@@ -54,7 +54,6 @@
 import org.eclipse.osee.ats.core.workflow.state.TeamState;
 import org.eclipse.osee.framework.core.data.ArtifactToken;
 import org.eclipse.osee.framework.core.data.BranchId;
-import org.eclipse.osee.framework.core.util.Result;
 import org.eclipse.osee.framework.jdk.core.result.XResultData;
 import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
 import org.eclipse.osee.framework.jdk.core.util.Collections;
@@ -70,7 +69,6 @@
 public class TransitionManager implements IExecuteListener {
 
    private final ITransitionHelper helper;
-   private String completedCancellationReason = null;
    private Date transitionOnDate;
    private final IAtsUserService userService;
    private final IAtsReviewService reviewService;
@@ -115,11 +113,6 @@
          return results;
       }
 
-      handleTransitionUi(results);
-      if (results.isCancelled() || !results.isEmpty()) {
-         return results;
-      }
-
       handleTransition(results);
       return results;
    }
@@ -144,21 +137,21 @@
     *
     * @return Result.isFalse if failure
     */
-   public void handleTransitionValidation(TransitionResults results) {
+   public TransitionResults handleTransitionValidation(TransitionResults results) {
       loadWorkItems();
       boolean overrideAssigneeCheck = helper.isOverrideAssigneeCheck();
       try {
          if (helper.getWorkItems().isEmpty()) {
             results.addResult(TransitionResult.NO_WORKFLOWS_PROVIDED_FOR_TRANSITION);
-            return;
+            return results;
          }
          if (helper.getToStateName() == null) {
             results.addResult(TransitionResult.TO_STATE_CANT_BE_NULL);
-            return;
+            return results;
          }
          if (!overrideAssigneeCheck && helper.isSystemUser()) {
             results.addResult(TransitionResult.CAN_NOT_TRANSITION_AS_SYSTEM_USER);
-            return;
+            return results;
          }
       } catch (OseeCoreException ex) {
          results.addResult(
@@ -246,6 +239,7 @@
                new TransitionResult(String.format("Exception while validating transition [%s]", helper.getName()), ex));
          }
       }
+      return results;
    }
 
    public void isTransitionValidForExtensions(TransitionResults results, IAtsWorkItem workItem, IAtsStateDefinition fromStateDef, IAtsStateDefinition toStateDef) {
@@ -284,28 +278,6 @@
    }
 
    /**
-    * Request extra information if transition requires hours spent prompt, cancellation reason, etc.
-    *
-    * @return results. if failure or TransitionResults.isCancelled if canceled
-    */
-   public void handleTransitionUi(TransitionResults results) {
-      Result result = helper.getCompleteOrCancellationReason();
-      if (result.isCancelled()) {
-         results.setCancelled(true);
-         return;
-      }
-      if (result.isTrue()) {
-         completedCancellationReason = result.getText();
-      }
-      result = helper.handleExtraHoursSpent(helper.getChangeSet());
-      if (result.isCancelled()) {
-         results.setCancelled(true);
-      } else if (result.isFalse()) {
-         results.addResult(new TransitionResult(result.getText()));
-      }
-   }
-
-   /**
     * Process transition and persist changes to given skynet transaction
     */
    public void handleTransition(TransitionResults results) {
@@ -330,21 +302,20 @@
                   }
 
                   if (toState.getStateType().isCancelledState()) {
-                     logWorkflowCancelledEvent(workItem, fromState, toState, completedCancellationReason,
-                        transitionDate, transitionUser, helper.getChangeSet(), attrResolver);
+                     logWorkflowCancelledEvent(workItem, fromState, toState, transitionDate, transitionUser,
+                        helper.getChangeSet(), attrResolver);
                   } else if (toState.getStateType().isCompletedState()) {
-                     logWorkflowCompletedEvent(workItem, fromState, toState, completedCancellationReason,
-                        transitionDate, transitionUser, helper.getChangeSet());
+                     logWorkflowCompletedEvent(workItem, fromState, toState, transitionDate, transitionUser,
+                        helper.getChangeSet());
                   } else {
-                     logStateCompletedEvent(workItem, workItem.getStateMgr().getCurrentStateName(),
-                        completedCancellationReason, transitionDate, transitionUser);
+                     logStateCompletedEvent(workItem, workItem.getStateMgr().getCurrentStateName(), transitionDate,
+                        transitionUser);
                   }
                   logStateStartedEvent(workItem, toState, transitionDate, transitionUser);
                   // Get transition to assignees, do some checking to ensure someone is assigneed and UnAssigned
                   List<? extends AtsUser> updatedAssigees = getToAssignees(workItem, toState);
 
-                  workItem.getStateMgr().transitionHelper(updatedAssigees, fromState, toState,
-                     completedCancellationReason);
+                  workItem.getStateMgr().transitionHelper(updatedAssigees, fromState, toState);
 
                   // Create validation review if in correct state and TeamWorkflow
                   if (reviewService.isValidationReviewRequired(workItem) && workItem.isTeamWorkflow()) {
@@ -498,13 +469,19 @@
       }
    }
 
-   public static void logWorkflowCancelledEvent(IAtsWorkItem workItem, IAtsStateDefinition fromState, IAtsStateDefinition toState, String reason, Date cancelDate, AtsUser cancelBy, IAtsChangeSet changes, IAttributeResolver attrResolver) {
-      workItem.getLog().addLog(LogType.StateCancelled, fromState.getName(), reason, cancelDate, cancelBy.getUserId());
+   private void logWorkflowCancelledEvent(IAtsWorkItem workItem, IAtsStateDefinition fromState, IAtsStateDefinition toState, Date cancelDate, AtsUser cancelBy, IAtsChangeSet changes, IAttributeResolver attrResolver) {
+      workItem.getLog().addLog(LogType.StateCancelled, fromState.getName(), helper.getCancellationReason(), cancelDate,
+         cancelBy.getUserId());
       if (attrResolver.isAttributeTypeValid(workItem, AtsAttributeTypes.CreatedBy)) {
          attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledBy, cancelBy.getUserId(), changes);
          attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledDate, cancelDate, changes);
-         if (Strings.isValid(reason)) {
-            attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledReason, reason, changes);
+         if (Strings.isValid(helper.getCancellationReason())) {
+            attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledReason,
+               helper.getCancellationReason(), changes);
+         }
+         if (Strings.isValid(helper.getCancellationReasonDetails())) {
+            attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledReasonDetails,
+               helper.getCancellationReasonDetails(), changes);
          }
          attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CancelledFromState, fromState.getName(),
             changes);
@@ -512,19 +489,19 @@
       validateUpdatePercentComplete(workItem, toState, changes);
    }
 
-   public static void logWorkflowUnCancelledEvent(IAtsWorkItem workItem, IAtsStateDefinition toState, IAtsChangeSet changes, IAttributeResolver attrResolver) {
+   private void logWorkflowUnCancelledEvent(IAtsWorkItem workItem, IAtsStateDefinition toState, IAtsChangeSet changes, IAttributeResolver attrResolver) {
       if (attrResolver.isAttributeTypeValid(workItem, AtsAttributeTypes.CreatedBy)) {
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CancelledBy, changes);
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CancelledDate, changes);
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CancelledReason, changes);
+         changes.deleteAttributes(workItem.getStoreObject(), AtsAttributeTypes.CancelledReasonDetails);
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CancelledFromState, changes);
       }
       validateUpdatePercentComplete(workItem, toState, changes);
    }
 
-   private void logWorkflowCompletedEvent(IAtsWorkItem workItem, IAtsStateDefinition fromState, IAtsStateDefinition toState, String reason, Date cancelDate, AtsUser cancelBy, IAtsChangeSet changes) {
-      workItem.getLog().addLog(LogType.StateComplete, fromState.getName(), Strings.isValid(reason) ? reason : "",
-         cancelDate, cancelBy.getUserId());
+   private void logWorkflowCompletedEvent(IAtsWorkItem workItem, IAtsStateDefinition fromState, IAtsStateDefinition toState, Date cancelDate, AtsUser cancelBy, IAtsChangeSet changes) {
+      workItem.getLog().addLog(LogType.StateComplete, fromState.getName(), "", cancelDate, cancelBy.getUserId());
       if (attrResolver.isAttributeTypeValid(workItem, AtsAttributeTypes.CreatedBy)) {
          attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CompletedBy, cancelBy.getUserId(), changes);
          attrResolver.setSoleAttributeValue(workItem, AtsAttributeTypes.CompletedDate, cancelDate, changes);
@@ -534,7 +511,7 @@
       validateUpdatePercentComplete(workItem, toState, changes);
    }
 
-   public static void logWorkflowUnCompletedEvent(IAtsWorkItem workItem, IAtsStateDefinition toState, IAtsChangeSet changes, IAttributeResolver attrResolver) {
+   private void logWorkflowUnCompletedEvent(IAtsWorkItem workItem, IAtsStateDefinition toState, IAtsChangeSet changes, IAttributeResolver attrResolver) {
       if (attrResolver.isAttributeTypeValid(workItem, AtsAttributeTypes.CreatedBy)) {
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CompletedBy, changes);
          attrResolver.deleteSoleAttribute(workItem, AtsAttributeTypes.CompletedDate, changes);
@@ -558,9 +535,8 @@
       }
    }
 
-   private void logStateCompletedEvent(IAtsWorkItem workItem, String fromStateName, String reason, Date date, AtsUser user) {
-      workItem.getLog().addLog(LogType.StateComplete, fromStateName, Strings.isValid(reason) ? reason : "", date,
-         user.getUserId());
+   private void logStateCompletedEvent(IAtsWorkItem workItem, String fromStateName, Date date, AtsUser user) {
+      workItem.getLog().addLog(LogType.StateComplete, fromStateName, "", date, user.getUserId());
    }
 
    public static void logStateStartedEvent(IAtsWorkItem workItem, IStateToken state, Date date, AtsUser user) {
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
index 518c77f..5c21a57 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
@@ -24,30 +24,26 @@
 import org.eclipse.osee.ats.api.event.IAtsWorkItemTopicEventListener;
 import org.eclipse.osee.ats.api.user.AtsUser;
 import org.eclipse.osee.ats.api.util.AtsTopicEvent;
-import org.eclipse.osee.ats.api.util.AtsUtil;
 import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.workdef.IAtsLayoutItem;
 import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
-import org.eclipse.osee.ats.api.workdef.model.RuleDefinitionOption;
 import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsWorkflowHook;
 import org.eclipse.osee.ats.api.workflow.transition.ITransitionHelper;
+import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionResults;
 import org.eclipse.osee.ats.core.workflow.transition.TransitionHelperAdapter;
-import org.eclipse.osee.ats.core.workflow.transition.TransitionStatusData;
 import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
 import org.eclipse.osee.ats.ide.internal.Activator;
 import org.eclipse.osee.ats.ide.internal.AtsClientService;
 import org.eclipse.osee.ats.ide.util.AtsUtilClient;
 import org.eclipse.osee.ats.ide.util.UserCheckTreeDialog;
-import org.eclipse.osee.ats.ide.util.widgets.dialog.TransitionStatusDialog;
 import org.eclipse.osee.ats.ide.workflow.AbstractWorkflowArtifact;
 import org.eclipse.osee.ats.ide.workflow.transition.TransitionResultsUi;
 import org.eclipse.osee.ats.ide.workflow.transition.TransitionToOperation;
 import org.eclipse.osee.framework.core.data.ArtifactId;
 import org.eclipse.osee.framework.core.operation.Operations;
-import org.eclipse.osee.framework.core.util.Result;
 import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
 import org.eclipse.osee.framework.jdk.core.util.Strings;
 import org.eclipse.osee.framework.logging.OseeLevel;
@@ -199,12 +195,8 @@
    }
 
    public static void handleTransitionButtonSelection(AbstractWorkflowArtifact awa, final boolean isEditable, IAtsStateDefinition toStateDef) {
-      final IAtsStateDefinition fromStateDef = awa.getStateDefinition();
-
       ITransitionHelper helper = new TransitionHelperAdapter(AtsClientService.get().getServices()) {
 
-         private IAtsChangeSet changes;
-
          @Override
          public String getToStateName() {
             return toStateDef.getName();
@@ -223,32 +215,7 @@
          }
 
          @Override
-         public Result handleExtraHoursSpent(final IAtsChangeSet changes) {
-            final Result result = new Result(true, "");
-            Displays.ensureInDisplayThread(new Runnable() {
-
-               @Override
-               public void run() {
-                  boolean resultBool = false;
-                  try {
-                     resultBool = handlePopulateStateMetrics(awa, fromStateDef, toStateDef, changes);
-                  } catch (OseeCoreException ex) {
-                     OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
-                     result.set(false);
-                     result.setText(String.format("Error processing extra hours spent for [%s]", awa.toStringWithId()));
-                  }
-                  if (!resultBool) {
-                     result.setCancelled(true);
-                     result.set(false);
-                  }
-               }
-            }, true);
-            return result;
-         }
-
-         @Override
-         public Result getCompleteOrCancellationReason() {
-            final Result result = new Result(true, "");
+         public TransitionData getCancellationReason(final TransitionData transitionData) {
             Displays.ensureInDisplayThread(new Runnable() {
 
                @Override
@@ -273,16 +240,15 @@
                            cancelDialog = new EntryDialog("Cancellation Reason", "Enter cancellation reason.");
                         }
                         if (cancelDialog.open() != 0) {
-                           result.setCancelled(true);
+                           transitionData.setDialogCancelled(true);
+                           return;
                         }
-                        result.set(true);
                         if (useEntryCancelWidgetDialog) {
-                           awa.setSoleAttributeFromString(AtsAttributeTypes.CancelReason,
-                              ((EntryCancelWidgetDialog) cancelDialog).getEntry());
-                           awa.setSoleAttributeFromString(AtsAttributeTypes.CancelledReasonDetails,
+                           transitionData.setCancellationReason(((EntryCancelWidgetDialog) cancelDialog).getEntry());
+                           transitionData.setCancellationReasonDetails(
                               ((EntryCancelWidgetDialog) cancelDialog).getCancelledDetails());
                         } else {
-                           result.setText(cancelDialog.getEntry());
+                           transitionData.setCancellationReason(cancelDialog.getEntry());
                         }
                      }
                   } catch (OseeCoreException ex) {
@@ -290,7 +256,7 @@
                   }
                }
             }, true);
-            return result;
+            return transitionData;
          }
 
          @Override
@@ -300,10 +266,7 @@
 
          @Override
          public IAtsChangeSet getChangeSet() {
-            if (changes == null) {
-               changes = AtsClientService.get().createChangeSet(getName());
-            }
-            return changes;
+            return null;
          }
 
          @Override
@@ -321,6 +284,16 @@
             return AtsClientService.get().getServices();
          }
 
+         @Override
+         public String getCancellationReasonDetails() {
+            return null;
+         }
+
+         @Override
+         public String getCancellationReason() {
+            return null;
+         }
+
       };
       final TransitionToOperation operation = new TransitionToOperation(helper);
       Operations.executeAsJob(operation, true, Job.SHORT, new JobChangeAdapter() {
@@ -337,46 +310,6 @@
       });
    }
 
-   private static boolean handlePopulateStateMetrics(AbstractWorkflowArtifact awa, IAtsStateDefinition fromStateDefinition, IAtsStateDefinition toStateDefinition, IAtsChangeSet changes) {
-      int percent = 0;
-      // If state weighting, always 100 cause state is completed
-      if (AtsClientService.get().getWorkDefinitionService().isStateWeightingEnabled(awa.getWorkDefinition())) {
-         percent = 100;
-      } else {
-         if (toStateDefinition.getStateType().isCompletedOrCancelledState()) {
-            percent = 100;
-         } else {
-            percent = awa.getSoleAttributeValue(AtsAttributeTypes.PercentComplete, 0);
-         }
-      }
-
-      double hoursSpent = awa.getStateMgr().getHoursSpent(awa.getCurrentStateName());
-      double additionalHours = 0.0;
-
-      if (isRequireStateHoursSpentPrompt(fromStateDefinition) && !toStateDefinition.getStateType().isCancelledState()) {
-         // Otherwise, open dialog to ask for hours complete
-         String msg = awa.getStateMgr().getCurrentStateName() + " State\n\n" + AtsUtil.doubleToI18nString(
-            hoursSpent) + " hours already spent on this state.\n" + "Enter the additional number of hours you spent on this state.";
-         // Remove after ATS Resolution options is removed 0.9.9_SR5ish
-         TransitionStatusData data = new TransitionStatusData(Arrays.asList(awa), false);
-         TransitionStatusDialog dialog = new TransitionStatusDialog("Enter Hours Spent", msg, data);
-         int result = dialog.open();
-         if (result == 0) {
-            additionalHours = dialog.getData().getAdditionalHours();
-         } else {
-            return false;
-         }
-      }
-      awa.getStateMgr().updateMetrics(awa.getStateDefinition(), additionalHours, percent, true,
-         AtsClientService.get().getUserService().getCurrentUser());
-      changes.add(awa);
-      return true;
-   }
-
-   private static boolean isRequireStateHoursSpentPrompt(IAtsStateDefinition stateDefinition) {
-      return stateDefinition.hasRule(RuleDefinitionOption.RequireStateHourSpentPrompt.name());
-   }
-
    public void updateTransitionToAssignees() {
       Collection<AtsUser> assignees = null;
       // Determine if the is an override set of assignees
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/section/WfeWorkflowSection.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/section/WfeWorkflowSection.java
index b47926b..ef66473 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/section/WfeWorkflowSection.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/section/WfeWorkflowSection.java
@@ -265,7 +265,7 @@
       xWidget.createWidgets(parent, 1);
       allXWidgets.add(xWidget);
       if (useBothWidgets) {
-         xWidget = new XCancellationReasonTextWidget(sma);
+         xWidget = new XCancellationReasonTextWidget(sma, editor);
          xWidget.addXModifiedListener(xModListener);
          xWidget.createWidgets(parent, 1);
          allXWidgets.add(xWidget);
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/ReviewInfoXWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/ReviewInfoXWidget.java
index b7c8c8c..b8ec013 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/ReviewInfoXWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/ReviewInfoXWidget.java
@@ -20,7 +20,6 @@
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.osee.ats.api.review.IAtsAbstractReview;
 import org.eclipse.osee.ats.api.review.ReviewFormalType;
-import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.workdef.IStateToken;
 import org.eclipse.osee.ats.api.workdef.model.ReviewBlockType;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionOption;
@@ -313,12 +312,11 @@
                            awas.add(revArt);
                         }
                      }
-                     IAtsChangeSet changes = AtsClientService.get().createChangeSet("Admin Auto-Complete Reviews");
                      TransitionHelper helper = new TransitionHelper("ATS Auto Complete Reviews",
                         org.eclipse.osee.framework.jdk.core.util.Collections.castAll(awas),
-                        TeamState.Completed.getName(), null, null, changes, AtsClientService.get().getServices(),
+                        TeamState.Completed.getName(), null, null, null, AtsClientService.get().getServices(),
                         TransitionOption.OverrideTransitionValidityCheck, TransitionOption.None);
-                     TransitionResults results = AtsClientService.get().getWorkItemService().transition(helper);
+                     TransitionResults results = AtsClientService.get().getWorkItemServiceClient().transition(helper);
                      if (!results.isEmpty()) {
                         AWorkbench.popup(String.format("Transition Error %s", results.toString()));
                      }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/TaskInfoXWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/TaskInfoXWidget.java
index 6a4c309..bd1943c 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/TaskInfoXWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/widget/TaskInfoXWidget.java
@@ -15,7 +15,6 @@
 import java.util.logging.Level;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.workdef.IStateToken;
 import org.eclipse.osee.ats.api.workdef.StateColor;
 import org.eclipse.osee.ats.api.workflow.IAtsTask;
@@ -180,7 +179,6 @@
                         return;
                      }
                      try {
-                        IAtsChangeSet changes = AtsClientService.get().createChangeSet("ATS Auto Complete Tasks");
                         for (IAtsTask task : AtsClientService.get().getTaskService().getTasks(teamWf, forState)) {
                            TaskArtifact taskArt = (TaskArtifact) task.getStoreObject();
                            if (!taskArt.isCompletedOrCancelled()) {
@@ -189,18 +187,17 @@
                                     AtsClientService.get().getUserService().getCurrentUser());
                               }
                               TransitionHelper helper = new TransitionHelper("Transition to Completed",
-                                 Arrays.asList(taskArt), TaskStates.Completed.getName(), null, null, changes,
+                                 Arrays.asList(taskArt), TaskStates.Completed.getName(), null, null, null,
                                  AtsClientService.get().getServices(), TransitionOption.OverrideTransitionValidityCheck,
                                  TransitionOption.None);
                               TransitionResults results =
-                                 AtsClientService.get().getWorkItemService().transition(helper);
+                                 AtsClientService.get().getWorkItemServiceClient().transition(helper);
                               if (!results.isEmpty()) {
                                  AWorkbench.popup(String.format("Transition Error %s", results.toString()));
                                  return;
                               }
                            }
                         }
-                        changes.execute();
                      } catch (OseeCoreException ex) {
                         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
                      }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/XCancellationReasonTextWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/XCancellationReasonTextWidget.java
index dabfeb3..aa8843d 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/XCancellationReasonTextWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/XCancellationReasonTextWidget.java
@@ -10,6 +10,10 @@
  *******************************************************************************/
 package org.eclipse.osee.ats.ide.util;
 
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
+import org.eclipse.osee.ats.ide.editor.event.IWfeEventHandle;
 import org.eclipse.osee.ats.ide.workflow.AbstractWorkflowArtifact;
 import org.eclipse.osee.framework.core.util.Result;
 import org.eclipse.osee.framework.jdk.core.util.Strings;
@@ -21,13 +25,14 @@
 /**
  * @author Donald G. Dunne
  */
-public class XCancellationReasonTextWidget extends XText implements IArtifactWidget {
+public class XCancellationReasonTextWidget extends XText implements IArtifactWidget, IWfeEventHandle {
 
    private AbstractWorkflowArtifact sma;
 
-   public XCancellationReasonTextWidget(AbstractWorkflowArtifact sma) {
+   public XCancellationReasonTextWidget(AbstractWorkflowArtifact sma, final WorkflowEditor editor) {
       super("Cancallation Reason");
       setArtifact(sma);
+      editor.registerEvent(this, AtsAttributeTypes.CancelledReason);
    }
 
    @Override
@@ -66,4 +71,9 @@
       return sma;
    }
 
+   @Override
+   public IAtsWorkItem getWorkItem() {
+      return sma;
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/AtsWorkItemServiceClientImpl.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/AtsWorkItemServiceClientImpl.java
index d55d03a..29cbee0 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/AtsWorkItemServiceClientImpl.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/AtsWorkItemServiceClientImpl.java
@@ -10,13 +10,17 @@
  *******************************************************************************/
 package org.eclipse.osee.ats.ide.workflow;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import org.eclipse.osee.ats.api.AtsApi;
 import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.user.AtsUser;
 import org.eclipse.osee.ats.api.util.AtsTopicEvent;
+import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
+import org.eclipse.osee.ats.api.workdef.StateType;
 import org.eclipse.osee.ats.api.workflow.ITeamWorkflowProvidersLazy;
 import org.eclipse.osee.ats.api.workflow.transition.ITransitionHelper;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
@@ -24,6 +28,7 @@
 import org.eclipse.osee.ats.core.workflow.AtsWorkItemServiceImpl;
 import org.eclipse.osee.ats.ide.internal.AtsClientService;
 import org.eclipse.osee.ats.ide.workflow.hooks.IAtsWorkflowHookIde;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
 import org.eclipse.osee.framework.jdk.core.util.Conditions;
 import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
 
@@ -56,6 +61,9 @@
       populateTransitionData(transData);
       TransitionResults results = atsApi.getServerEndpoints().getActionEndpoint().transition(transData);
       results.setAtsApi(atsApi);
+      if (results.isErrors()) {
+         return results;
+      }
       results = postEventAndReturn(transData, results);
       return results;
    }
@@ -71,7 +79,40 @@
 
    @Override
    public TransitionResults transition(ITransitionHelper helper) {
-      TransitionResults results = transition(helper.getTransData());
+      // Have to handle validation separate so UI can be done before transition
+      helper.setAtsApi(atsApi);
+      TransitionData transData = helper.getTransData();
+      if (helper.getWorkItems().size() == 1) {
+         Collection<? extends AtsUser> toAssignees = helper.getToAssignees(helper.getWorkItems().iterator().next());
+         if (toAssignees != null) {
+            transData.setToAssignees(Collections.castAll(toAssignees));
+         }
+      }
+      if (helper.getTransitionUser() != null) {
+         transData.setTransitionUser(helper.getTransitionUser());
+      }
+      transData.setToStateName(helper.getToStateName());
+      transData.setName(helper.getName());
+      transData.setWorkItems(helper.getWorkItems());
+
+      // Set dummy cancel reason
+      IAtsStateDefinition toStateDef = AtsClientService.get().getWorkDefinitionService().getStateDefinitionByName(
+         helper.getWorkItems().iterator().next(), helper.getToStateName());
+      if (toStateDef.getStateType() == StateType.Cancelled) {
+         transData.setCancellationReason("temp reason");
+      }
+      TransitionResults results = transitionValidate(transData);
+      if (results.isErrors()) {
+         return results;
+      }
+
+      helper.getCancellationReason(transData);
+      if (transData.isDialogCancelled()) {
+         results.setCancelled(true);
+         return results;
+      }
+
+      results = transition(transData);
       results.setAtsApi(atsApi);
       return results;
    }
@@ -81,7 +122,6 @@
       populateTransitionData(transData);
       TransitionResults results = atsApi.getServerEndpoints().getActionEndpoint().transitionValidate(transData);
       results.setAtsApi(atsApi);
-      results = postEventAndReturn(transData, results);
       return results;
    }
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToMenu.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToMenu.java
index 51c4498..665b44f 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToMenu.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToMenu.java
@@ -28,27 +28,22 @@
 import org.eclipse.nebula.widgets.xviewer.XViewer;
 import org.eclipse.osee.ats.api.AtsApi;
 import org.eclipse.osee.ats.api.IAtsWorkItem;
-import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
 import org.eclipse.osee.ats.api.user.AtsUser;
 import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.workdef.IAtsLayoutItem;
 import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
-import org.eclipse.osee.ats.api.workdef.model.RuleDefinitionOption;
 import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
 import org.eclipse.osee.ats.api.workflow.transition.ITransitionHelper;
+import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
 import org.eclipse.osee.ats.api.workflow.transition.TransitionResults;
 import org.eclipse.osee.ats.core.workflow.state.TeamState;
 import org.eclipse.osee.ats.core.workflow.transition.TransitionHelperAdapter;
-import org.eclipse.osee.ats.core.workflow.transition.TransitionStatusData;
 import org.eclipse.osee.ats.ide.AtsImage;
-import org.eclipse.osee.ats.ide.editor.tab.workflow.util.WfePromptChangeStatus;
 import org.eclipse.osee.ats.ide.internal.Activator;
 import org.eclipse.osee.ats.ide.internal.AtsClientService;
 import org.eclipse.osee.ats.ide.util.AtsUtilClient;
-import org.eclipse.osee.ats.ide.util.widgets.dialog.TransitionStatusDialog;
 import org.eclipse.osee.ats.ide.workflow.AbstractWorkflowArtifact;
 import org.eclipse.osee.framework.core.operation.Operations;
-import org.eclipse.osee.framework.core.util.Result;
 import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
@@ -169,68 +164,6 @@
    private static void handleTransitionToSelected(final String toStateName, final Set<IAtsWorkItem> workItems) {
       final ITransitionHelper helper = new TransitionHelperAdapter(AtsClientService.get().getServices()) {
 
-         private IAtsChangeSet changes;
-
-         @Override
-         public Result handleExtraHoursSpent(final IAtsChangeSet changes) {
-            final Result result = new Result(true, "");
-            Displays.ensureInDisplayThread(new Runnable() {
-
-               @Override
-               public void run() {
-                  try {
-                     IAtsStateDefinition toStateDef =
-                        AtsClientService.get().getWorkDefinitionService().getStateDefinitionByName(
-                           workItems.iterator().next(), toStateName);
-
-                     IAtsStateDefinition fromStateDefinition = workItems.iterator().next().getStateDefinition();
-                     if (isRequireStateHoursSpentPrompt(
-                        fromStateDefinition) && !toStateDef.getStateType().isCancelledState()) {
-
-                        boolean showPercentCompleted = !toStateDef.getStateType().isCompletedOrCancelledState();
-                        TransitionStatusData data = new TransitionStatusData(getWorkItems(), showPercentCompleted);
-                        if (toStateDef.getRecommendedPercentComplete() != null) {
-                           data.setDefaultPercent(toStateDef.getRecommendedPercentComplete());
-                           data.setPercent(100);
-                        } else if (toStateDef.getStateType().isCompletedOrCancelledState()) {
-                           data.setDefaultPercent(100);
-                           data.setPercent(100);
-                        }
-                        String title = null;
-                        String message = null;
-                        if (data.isPercentRequired()) {
-                           title = "Enter Percent and Hours Spent";
-                           message = "Enter percent complete and additional hours spent in current state(s)";
-                        } else {
-                           title = "Enter Hours Spent";
-                           message = "Enter additional hours spent in current state(s)";
-                        }
-                        TransitionStatusDialog dialog = new TransitionStatusDialog(title, message, data);
-
-                        int dialogResult = dialog.open();
-                        if (dialogResult == 0) {
-                           try {
-                              WfePromptChangeStatus.performChangeStatus(workItems, null, data.getAdditionalHours(),
-                                 data.getPercent(), data.isSplitHoursBetweenItems(), changes);
-                           } catch (OseeCoreException ex) {
-                              OseeLog.log(Activator.class, Level.SEVERE, ex);
-                              result.set(false);
-                              result.setTextWithFormat(
-                                 "Exception handling extra hours spent for transition to [%s] (see log)",
-                                 getToStateName());
-                           }
-                        } else {
-                           result.setCancelled(true);
-                        }
-                     }
-                  } catch (OseeCoreException ex1) {
-                     OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex1);
-                  }
-               }
-            }, true);
-            return result;
-         }
-
          @Override
          public String getToStateName() {
             return toStateName;
@@ -247,8 +180,7 @@
          }
 
          @Override
-         public Result getCompleteOrCancellationReason() {
-            final Result result = new Result(false, "");
+         public TransitionData getCancellationReason(TransitionData transitionData) {
             Displays.ensureInDisplayThread(new Runnable() {
 
                @Override
@@ -263,7 +195,6 @@
                   }
                   if (stateDef != null && stateDef.getStateType().isCancelledState()) {
                      EntryDialog cancelDialog;
-                     AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) workItem;
                      boolean useEntryCancelWidgetDialog = false;
                      for (IAtsLayoutItem layoutItem : stateDef.getLayoutItems()) {
                         if (layoutItem.getName().contains("Cancel")) {
@@ -278,22 +209,20 @@
                         cancelDialog = new EntryDialog("Cancellation Reason", "Enter cancellation reason.");
                      }
                      if (cancelDialog.open() != 0) {
-                        result.setCancelled(true);
+                        transitionData.setDialogCancelled(true);
                      }
-                     result.set(true);
                      if (useEntryCancelWidgetDialog) {
-                        awa.setSoleAttributeFromString(AtsAttributeTypes.CancelReason,
-                           ((EntryCancelWidgetDialog) cancelDialog).getEntry());
-                        awa.setSoleAttributeFromString(AtsAttributeTypes.CancelledReasonDetails,
+                        transitionData.setCancellationReason(((EntryCancelWidgetDialog) cancelDialog).getEntry());
+                        transitionData.setCancellationReasonDetails(
                            ((EntryCancelWidgetDialog) cancelDialog).getCancelledDetails());
                      } else {
-                        result.setText(cancelDialog.getEntry());
+                        transitionData.setCancellationReason(cancelDialog.getEntry());
                      }
                   }
                }
 
             }, true);
-            return result;
+            return transitionData;
          }
 
          @Override
@@ -303,10 +232,7 @@
 
          @Override
          public IAtsChangeSet getChangeSet() {
-            if (changes == null) {
-               changes = AtsClientService.get().createChangeSet(getName());
-            }
-            return changes;
+            return null;
          }
 
          @Override
@@ -325,6 +251,16 @@
             return AtsClientService.get().getServices();
          }
 
+         @Override
+         public String getCancellationReasonDetails() {
+            return null;
+         }
+
+         @Override
+         public String getCancellationReason() {
+            return null;
+         }
+
       };
       final TransitionToOperation operation = new TransitionToOperation(helper);
       Operations.executeAsJob(operation, true, Job.SHORT, new JobChangeAdapter() {
@@ -346,8 +282,4 @@
       });
    }
 
-   private static boolean isRequireStateHoursSpentPrompt(IAtsStateDefinition stateDefinition) {
-      return stateDefinition.hasRule(RuleDefinitionOption.RequireStateHourSpentPrompt.name());
-   }
-
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToOperation.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToOperation.java
index 9a5616e..4d27aba 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToOperation.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/transition/TransitionToOperation.java
@@ -49,13 +49,12 @@
          }
          changes.executeIfNeeded();
 
-         results = AtsClientService.get().getWorkItemService().transition(helper);
-         if (!results.isEmpty()) {
-            TransitionResultsUi.report("Transition", results);
-         }
+         results = AtsClientService.get().getWorkItemServiceClient().transition(helper);
       } catch (OseeCoreException ex) {
          OseeLog.log(Activator.class, Level.SEVERE, ex);
-         results = new TransitionResults();
+         if (results == null) {
+            results = new TransitionResults();
+         }
          results.addResult(
             new TransitionResult(String.format("Exception [%s] transitioning to [%s].  See error log for details.",
                ex.getLocalizedMessage(), helper.getToStateName())));