Coverage Report - org.kuali.student.core.workflow.ui.client.widgets.WorkflowUtilities
 
Classes in this File Line Coverage Branch Coverage Complexity
WorkflowUtilities
0%
0/289
0%
0/120
2.073
WorkflowUtilities$1
0%
0/11
0%
0/8
2.073
WorkflowUtilities$10
0%
0/23
N/A
2.073
WorkflowUtilities$10$1
0%
0/8
0%
0/4
2.073
WorkflowUtilities$10$1$1
0%
0/12
0%
0/4
2.073
WorkflowUtilities$10$2
0%
0/5
0%
0/2
2.073
WorkflowUtilities$11
0%
0/32
0%
0/8
2.073
WorkflowUtilities$11$1
0%
0/12
0%
0/6
2.073
WorkflowUtilities$11$1$1
0%
0/6
N/A
2.073
WorkflowUtilities$11$1$1$1
0%
0/8
0%
0/2
2.073
WorkflowUtilities$11$1$1$1$1
0%
0/3
N/A
2.073
WorkflowUtilities$11$1$2
0%
0/12
0%
0/4
2.073
WorkflowUtilities$11$2
0%
0/5
0%
0/4
2.073
WorkflowUtilities$11$3
0%
0/5
0%
0/4
2.073
WorkflowUtilities$11$4
0%
0/5
0%
0/2
2.073
WorkflowUtilities$12
0%
0/23
N/A
2.073
WorkflowUtilities$12$1
0%
0/8
0%
0/4
2.073
WorkflowUtilities$12$1$1
0%
0/12
0%
0/4
2.073
WorkflowUtilities$12$2
0%
0/5
0%
0/2
2.073
WorkflowUtilities$13
0%
0/25
0%
0/4
2.073
WorkflowUtilities$13$1
0%
0/13
0%
0/6
2.073
WorkflowUtilities$13$1$1
0%
0/7
0%
0/2
2.073
WorkflowUtilities$13$1$1$1
0%
0/3
N/A
2.073
WorkflowUtilities$13$1$1$1$1
0%
0/15
0%
0/6
2.073
WorkflowUtilities$13$1$1$1$1$1
0%
0/3
N/A
2.073
WorkflowUtilities$13$1$2
0%
0/13
0%
0/4
2.073
WorkflowUtilities$13$2
0%
0/5
0%
0/2
2.073
WorkflowUtilities$14
0%
0/7
0%
0/2
2.073
WorkflowUtilities$15
0%
0/8
0%
0/2
2.073
WorkflowUtilities$16
0%
0/28
N/A
2.073
WorkflowUtilities$16$1
0%
0/14
0%
0/14
2.073
WorkflowUtilities$16$1$1
0%
0/12
0%
0/4
2.073
WorkflowUtilities$16$2
0%
0/5
0%
0/4
2.073
WorkflowUtilities$16$3
0%
0/5
0%
0/4
2.073
WorkflowUtilities$17
0%
0/5
N/A
2.073
WorkflowUtilities$18
0%
0/3
N/A
2.073
WorkflowUtilities$18$1
0%
0/6
0%
0/2
2.073
WorkflowUtilities$19
0%
0/4
N/A
2.073
WorkflowUtilities$2
0%
0/4
N/A
2.073
WorkflowUtilities$20
0%
0/3
N/A
2.073
WorkflowUtilities$20$1
0%
0/14
0%
0/6
2.073
WorkflowUtilities$3
0%
0/7
N/A
2.073
WorkflowUtilities$4
0%
0/4
N/A
2.073
WorkflowUtilities$4$1
0%
0/13
0%
0/4
2.073
WorkflowUtilities$5
0%
0/4
N/A
2.073
WorkflowUtilities$6
0%
0/5
N/A
2.073
WorkflowUtilities$7
0%
0/5
N/A
2.073
WorkflowUtilities$8
0%
0/4
N/A
2.073
WorkflowUtilities$8$1
0%
0/10
0%
0/4
2.073
WorkflowUtilities$9
0%
0/19
N/A
2.073
WorkflowUtilities$9$1
0%
0/6
0%
0/2
2.073
WorkflowUtilities$9$1$1
0%
0/12
0%
0/4
2.073
WorkflowUtilities$9$2
0%
0/5
0%
0/2
2.073
WorkflowUtilities$DecisionRationaleDetail
0%
0/21
0%
0/4
2.073
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  * 
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 package org.kuali.student.core.workflow.ui.client.widgets;
 16  
 
 17  
 import java.util.ArrayList;
 18  
 import java.util.HashSet;
 19  
 import java.util.List;
 20  
 
 21  
 import org.kuali.student.common.assembly.data.Metadata;
 22  
 import org.kuali.student.common.assembly.data.MetadataInterrogator;
 23  
 import org.kuali.student.common.assembly.data.ModelDefinition;
 24  
 import org.kuali.student.common.assembly.data.QueryPath;
 25  
 import org.kuali.student.common.dto.DtoConstants.DtoState;
 26  
 import org.kuali.student.common.dto.RichTextInfo;
 27  
 import org.kuali.student.common.ui.client.application.Application;
 28  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 29  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 30  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptorReadOnly;
 31  
 import org.kuali.student.common.ui.client.configurable.mvc.LayoutController;
 32  
 import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle;
 33  
 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
 34  
 import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
 35  
 import org.kuali.student.common.ui.client.event.ActionEvent;
 36  
 import org.kuali.student.common.ui.client.event.SaveActionEvent;
 37  
 import org.kuali.student.common.ui.client.mvc.ActionCompleteCallback;
 38  
 import org.kuali.student.common.ui.client.mvc.Callback;
 39  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 40  
 import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
 41  
 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
 42  
 import org.kuali.student.common.ui.client.util.SearchUtils;
 43  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
 44  
 import org.kuali.student.common.ui.client.widgets.KSDropDown;
 45  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 46  
 import org.kuali.student.common.ui.client.widgets.KSLightBox;
 47  
 import org.kuali.student.common.ui.client.widgets.KSRichEditor;
 48  
 import org.kuali.student.common.ui.client.widgets.StylishDropDown;
 49  
 import org.kuali.student.common.ui.client.widgets.buttongroups.AcknowledgeCancelGroup;
 50  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
 51  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.AcknowledgeCancelEnum;
 52  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.ConfirmCancelEnum;
 53  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.RejectCancelEnum;
 54  
 import org.kuali.student.common.ui.client.widgets.buttongroups.ConfirmCancelGroup;
 55  
 import org.kuali.student.common.ui.client.widgets.buttongroups.RejectCancelGroup;
 56  
 import org.kuali.student.common.ui.client.widgets.dialog.ConfirmationDialog;
 57  
 import org.kuali.student.common.ui.client.widgets.field.layout.button.ActionCancelGroup;
 58  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.AbbrPanel;
 59  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
 60  
 import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
 61  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
 62  
 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
 63  
 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
 64  
 import org.kuali.student.common.ui.client.widgets.menus.KSMenuItemData;
 65  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
 66  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
 67  
 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
 68  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 69  
 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
 70  
 import org.kuali.student.core.comment.dto.CommentInfo;
 71  
 import org.kuali.student.core.comments.ui.client.service.CommentRpcService;
 72  
 import org.kuali.student.core.comments.ui.client.service.CommentRpcServiceAsync;
 73  
 import org.kuali.student.core.proposal.dto.ProposalInfo;
 74  
 import org.kuali.student.core.proposal.ui.client.service.ProposalRpcService;
 75  
 import org.kuali.student.core.proposal.ui.client.service.ProposalRpcServiceAsync;
 76  
 import org.kuali.student.core.workflow.ui.client.WorkflowConstants;
 77  
 import org.kuali.student.core.workflow.ui.client.service.WorkflowRpcService;
 78  
 import org.kuali.student.core.workflow.ui.client.service.WorkflowRpcServiceAsync;
 79  
 
 80  
 import com.google.gwt.core.client.GWT;
 81  
 import com.google.gwt.event.dom.client.ClickEvent;
 82  
 import com.google.gwt.event.dom.client.ClickHandler;
 83  
 import com.google.gwt.event.dom.client.KeyUpEvent;
 84  
 import com.google.gwt.event.dom.client.KeyUpHandler;
 85  
 import com.google.gwt.user.client.Window;
 86  
 import com.google.gwt.user.client.rpc.AsyncCallback;
 87  
 import com.google.gwt.user.client.ui.HorizontalPanel;
 88  
 import com.google.gwt.user.client.ui.VerticalPanel;
 89  
 import com.google.gwt.user.client.ui.Widget;
 90  
 
 91  0
 public class WorkflowUtilities{
 92  
 
 93  
         //TODO: This should come from the ReferenceModel like it does in CommentTool
 94  
     public static final String PROPOSAL_REF_TYPE_KEY = "referenceType.clu.proposal";
 95  
     
 96  0
         public static enum DecisionRationaleDetail {
 97  0
         APPROVE("kuali.comment.type.workflowDecisionRationale.approve", "Approved"),
 98  0
         REJECT("kuali.comment.type.workflowDecisionRationale.reject", "Rejected"),
 99  0
         RETURN_TO_PREVIOUS("kuali.comment.type.workflowDecisionRationale.return", "Sent for Revisions"),
 100  0
         WITHDRAW("kuali.comment.type.workflowDecisionRationale.withdraw", "Withdrawn"),
 101  0
         ACKNOWLEDGE("kuali.comment.type.workflowDecisionRationale.acknowledge", "Acknowledged"),
 102  0
         FYI("kuali.comment.type.workflowDecisionRationale.fyi", "FYI"),
 103  0
         CANCEL_WORKFLOW("kuali.comment.type.workflowDecisionRationale.cancelWorkflow", "Cancelled"),
 104  0
         BLANKET_APPROVE("kuali.comment.type.workflowDecisionRationale.blanketApprove", "Blanket Approved")
 105  
         ;
 106  
 
 107  0
         private String type = "";
 108  0
         private String label = "";
 109  
         
 110  
         
 111  
 
 112  0
         private DecisionRationaleDetail(String type, String label) {
 113  0
             this.type = type;
 114  0
             this.label = label;
 115  0
         }
 116  
 
 117  
         public String getType() {
 118  0
             return type;
 119  
         }
 120  
 
 121  
         public String getLabel() {
 122  0
             return label;
 123  
         }
 124  
 
 125  
         public static DecisionRationaleDetail getByType(String type) {
 126  0
             for (DecisionRationaleDetail detail : DecisionRationaleDetail.values()) {
 127  0
                 if (detail.getType().equals(type)) {
 128  0
                     return detail;
 129  
                 }
 130  
             }
 131  0
             return null;
 132  
         }
 133  
 
 134  
     }
 135  
 
 136  0
         DataModel dataModel=null;
 137  
         
 138  
 
 139  
         
 140  0
         boolean loaded=false;
 141  
     
 142  0
     private boolean workflowWidgetsEnabled = true;
 143  
         
 144  
         private KSMenuItemData wfApproveItem;
 145  
         private KSMenuItemData wfDisApproveItem;
 146  
         private KSMenuItemData wfAcknowledgeItem;
 147  
         private KSMenuItemData wfStartWorkflowItem;
 148  
     private KSMenuItemData wfCancelWorkflowItem;
 149  
         private KSMenuItemData wfFYIWorkflowItem;
 150  
         private KSMenuItemData wfWithdrawItem;
 151  
     private KSMenuItemData wfReturnToPreviousItem;
 152  
     private KSMenuItemData wfBlanketApproveItem;
 153  
         
 154  0
         private final List<KSMenuItemData> items = new ArrayList<KSMenuItemData>();
 155  0
         private final List<KSMenuItemData> additionalItems = new ArrayList<KSMenuItemData>();
 156  
 
 157  
         
 158  
     SaveActionEvent approveSaveActionEvent;
 159  
     SaveActionEvent startWorkflowSaveActionEvent;
 160  
     
 161  0
     WorkflowRpcServiceAsync workflowRpcServiceAsync = GWT.create(WorkflowRpcService.class);
 162  0
     private final CommentRpcServiceAsync commentServiceAsync = GWT.create(CommentRpcService.class);
 163  0
     private final ProposalRpcServiceAsync proposalServiceAsync = GWT.create(ProposalRpcService.class);
 164  
     
 165  
     private String modelName;
 166  
     private String proposalPath;
 167  0
     private String proposalId = "";
 168  
     private String workflowId;
 169  0
     private String proposalName="";
 170  0
     private String workflowActions="";
 171  
         
 172  0
         private final List<StylishDropDown> workflowWidgets = new ArrayList<StylishDropDown>();
 173  
         private Callback<Boolean> submitCallback;
 174  0
         private final ConfirmationDialog dialog = new ConfirmationDialog("Submit Proposal", "Are you sure you want to submit the proposal to workflow?", "Submit");
 175  
         private AbbrPanel required; 
 176  
         private KSLightBox submitSuccessDialog;
 177  
         private VerticalPanel dialogPanel;
 178  
         private VerticalSectionView approveDialogView;
 179  
         private VerticalSectionView blanketApproveDialogView;
 180  0
         private HashSet<String> ignoredApproveDialogFields = new HashSet<String>();
 181  
     
 182  0
     private final KSLabel workflowStatusLabel = new KSLabel("");
 183  
     
 184  0
     private final KSLabel proposalStatusLabel = new KSLabel("");
 185  
 
 186  
     private final LayoutController parentController;
 187  
 
 188  0
         private String dropDownLabel = "Workflow Actions";
 189  
         
 190  0
         ActionCancelGroup approveCancelButtons = new ActionCancelGroup(ButtonEnumerations.ApproveCancelEnum.APPROVE, ButtonEnumerations.ApproveCancelEnum.CANCEL); 
 191  
         
 192  0
         public WorkflowUtilities(LayoutController parentController, String proposalPath) {
 193  0
                 this.parentController = parentController;
 194  0
                 this.proposalPath = proposalPath;
 195  0
                 setupWFButtons();
 196  0
                 setupDialog();
 197  0
         }
 198  
         
 199  0
         public WorkflowUtilities(LayoutController parentController, String proposalPath, String dropDownLabel) {
 200  0
                 this.dropDownLabel = dropDownLabel;
 201  0
                 this.parentController = parentController;
 202  0
                 this.proposalPath = proposalPath;
 203  0
                 setupWFButtons();
 204  0
                 setupDialog();
 205  0
         }
 206  
         
 207  0
         public WorkflowUtilities(LayoutController parentController, String proposalPath, String dropDownLabel, Enum<?> viewEnum, String name, String modelId) {
 208  0
                 this.dropDownLabel = dropDownLabel;
 209  0
                 this.parentController = parentController;
 210  0
                 this.proposalPath = proposalPath;
 211  
 
 212  0
                 approveDialogView = new VerticalSectionView(viewEnum, name, modelId);
 213  0
                 approveDialogView.setController(parentController);
 214  
                 
 215  0
                 blanketApproveDialogView = new VerticalSectionView(viewEnum, name, modelId);
 216  0
                 blanketApproveDialogView.setController(parentController);
 217  
                 
 218  0
                 setupWFButtons();
 219  0
                 setupDialog();
 220  0
         }
 221  
         
 222  
         public void addApproveDialogMsg(String messageText) {
 223  0
             KSLabel textArea = new KSLabel();
 224  0
             textArea.setText(messageText);
 225  
             
 226  0
             approveDialogView.addWidget(textArea);
 227  0
         }
 228  
         
 229  
         public FieldDescriptor addApproveDialogField(String parentPath, String fieldKey, MessageKeyInfo messageKey, ModelDefinition modelDefinition, boolean forceAdd){
 230  0
             return addApproveDialogField(parentPath, fieldKey, messageKey, modelDefinition, forceAdd, false, null);
 231  
 
 232  
         }
 233  
         
 234  
            public FieldDescriptor addApproveDialogField(String parentPath, String fieldKey, MessageKeyInfo messageKey, ModelDefinition modelDefinition, boolean forceAdd, boolean readOnly){
 235  0
                 return addApproveDialogField(parentPath, fieldKey, messageKey, modelDefinition, forceAdd, readOnly, null);
 236  
 
 237  
             }
 238  
 
 239  
         public FieldDescriptor addApproveDialogField(String parentPath, String fieldKey, MessageKeyInfo messageKey, ModelDefinition modelDefinition, boolean forceAdd, boolean readOnly, Widget widget){
 240  
 
 241  0
                 QueryPath path = QueryPath.concat(parentPath, fieldKey);
 242  0
         Metadata meta = modelDefinition.getMetadata(path);
 243  
         
 244  
         FieldDescriptor blanketApproveFd;
 245  
         FieldDescriptor approveFd;
 246  
         
 247  
         //Always add to blanket approve 
 248  0
         if(blanketApproveDialogView != null){
 249  0
             if(!readOnly){
 250  0
                 blanketApproveFd = new FieldDescriptor(path.toString(), messageKey, meta);
 251  
             } else {
 252  0
                 blanketApproveFd = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
 253  
             }
 254  0
             blanketApproveFd.setHasHadFocus(true);
 255  0
                 blanketApproveDialogView.addField(blanketApproveFd);
 256  
         }
 257  
         
 258  
                 //Add a new field to the workflow widget
 259  0
         if (meta != null){
 260  0
                 if(approveDialogView != null){
 261  0
                 if(forceAdd || 
 262  
                                 (meta.isCanEdit() && 
 263  
                                                 (MetadataInterrogator.isRequiredForNextState(meta) || 
 264  
                                                                 (meta.getConstraints() != null && meta.getConstraints().get(0)!=null && meta.getConstraints().get(0).getMinOccurs()!= null && meta.getConstraints().get(0).getMinOccurs()>0)))){
 265  0
                     if(!readOnly){
 266  0
                         approveFd = new FieldDescriptor(path.toString(), messageKey, meta);
 267  
                     } else {
 268  0
                         approveFd = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
 269  
                     }
 270  0
                     approveFd.setHasHadFocus(true);
 271  0
                         approveDialogView.addField(approveFd);
 272  0
                     return approveFd;
 273  
                 }
 274  
                 }
 275  
         }
 276  0
                 return null;
 277  
         }
 278  
         
 279  
         public void updateApproveFields(){
 280  0
                 parentController.requestModel(new ModelRequestCallback<DataModel>(){
 281  
                         public void onModelReady(final DataModel model) {
 282  0
                                 if(approveDialogView!=null){
 283  0
                                         approveDialogView.updateView(model);
 284  0
                                         for (final FieldDescriptor fd:approveDialogView.getFields()){
 285  0
                                                 updateCrossField(fd,model);
 286  
                                         }
 287  
                                 }
 288  0
                                 if(blanketApproveDialogView!=null){
 289  0
                                         blanketApproveDialogView.updateView(model);
 290  0
                                         for (final FieldDescriptor fd:blanketApproveDialogView.getFields()){
 291  0
                                                 updateCrossField(fd,model);
 292  
                                         }
 293  
                                 }
 294  0
                         }
 295  
                         public void onRequestFail(Throwable cause) {
 296  0
                         }
 297  
                         
 298  
                 });
 299  0
         }
 300  
         
 301  
         /**
 302  
          * Updates and binds all of the dependent fields for the field passed in as a parameter. 
 303  
          * Then reprocesses constraints on the field passed in so it is correctly constrained.
 304  
          * This is needed since the data values won't be bound to the fields until those sections are displayed
 305  
          *
 306  
          * TODO This static class should be moved to a utility at some point
 307  
          *   
 308  
          * @param fd the field with cross constraints that needs updating
 309  
          * @param dataModel
 310  
          */
 311  
         public static void updateCrossField(final FieldDescriptor fd, final DataModel dataModel){
 312  
         // Update the widgets of any cross constraints so the values are there and can be reprocessed.
 313  0
         if (fd.getFieldWidget() instanceof KSPicker && ((KSPicker) fd.getFieldWidget()).getInputWidget() instanceof KSSelectItemWidgetAbstract) {
 314  0
             if (fd.getFieldWidget() instanceof HasCrossConstraints) {
 315  0
                 HashSet<String> constraints = ((HasCrossConstraints) fd.getFieldWidget()).getCrossConstraints();
 316  0
                 if (constraints != null) {
 317  0
                     for (String path : constraints) {
 318  0
                         final String finalPath = SearchUtils.resolvePath(path);
 319  0
                         final FieldDescriptor crossField = Application.getApplicationContext().getPathToFieldMapping(null, finalPath);
 320  0
                         if (crossField != null) {
 321  0
                             final ModelWidgetBinding mwb = crossField.getModelWidgetBinding();
 322  0
                             if (mwb != null) {
 323  
                                 // This insanity is needed because setting a widget value can be asynchronous.
 324  
                                 // Adds a callback and reprocesses constraints after the value has actually been set
 325  0
                                 if (crossField.getFieldWidget() instanceof KSPicker && ((KSPicker) crossField.getFieldWidget()).getInputWidget() instanceof KSSelectItemWidgetAbstract) {
 326  0
                                     ((KSSelectItemWidgetAbstract) ((KSPicker) crossField.getFieldWidget()).getInputWidget()).addWidgetReadyCallback(new Callback<Widget>() {
 327  
                                         public void exec(Widget result) {
 328  0
                                             mwb.setWidgetValue(crossField.getFieldWidget(), dataModel, finalPath);
 329  0
                                             ((HasCrossConstraints) fd.getFieldWidget()).reprocessWithUpdatedConstraints();
 330  0
                                         }
 331  
                                     });
 332  
                                 } else {
 333  0
                                     mwb.setWidgetValue(crossField.getFieldWidget(), dataModel, finalPath);
 334  
                                 }
 335  
                             }
 336  
                         }
 337  0
                     }
 338  
                 }
 339  0
                 ((HasCrossConstraints) fd.getFieldWidget()).reprocessWithUpdatedConstraints();
 340  
             }
 341  
         }
 342  0
     }
 343  
         public void requestAndSetupModel(final Callback<Boolean> onModelReadyCallback) {
 344  
                 
 345  0
                 if(null==dataModel){
 346  
                         //Get the Model from the controller and register a model change handler when the workflow model is updated
 347  0
                         parentController.requestModel(modelName, new ModelRequestCallback<DataModel>() {
 348  
                         
 349  
                                 @Override
 350  
                                 public void onRequestFail(Throwable cause) {
 351  0
                                         Window.alert("Model Request Failed. "+cause.getMessage());
 352  0
                                 }
 353  
 
 354  
                                 @Override
 355  
                                 public void onModelReady(DataModel model) {
 356  
                                         //After we get the model update immediately
 357  0
                                         dataModel = model;
 358  0
                                         updateWorkflow(dataModel);
 359  0
                                         onModelReadyCallback.exec(true);
 360  0
                                 }
 361  
                         });
 362  
                 }else{
 363  
                         //If the model has been set don't waste time finding it again and don't register 
 364  
                         //another change listener, just update
 365  0
                         updateWorkflow(dataModel);
 366  0
                         onModelReadyCallback.exec(true);
 367  
                 }
 368  0
         }
 369  
         
 370  
         private void setupWFButtons() {
 371  0
                 wfApproveItem = getApproveItem();
 372  0
                 wfDisApproveItem = getDisApproveItem();
 373  0
                 wfAcknowledgeItem = getAcknowledgeItem();
 374  0
                 wfStartWorkflowItem = getStartItem();
 375  0
                 wfCancelWorkflowItem = getCancelWorkflowItem();
 376  0
                 wfFYIWorkflowItem = getFYIWorkflowItem();
 377  0
                 wfWithdrawItem = getWithdrawItem();
 378  0
                 wfReturnToPreviousItem = getReturnToPreviousItem();
 379  0
                 wfBlanketApproveItem = getBlanketApproveItem();
 380  0
         }
 381  
         
 382  
         private void setupSubmitSuccessDialog(){
 383  0
                 if(submitSuccessDialog==null){
 384  0
                         submitSuccessDialog= new KSLightBox();
 385  0
                         submitSuccessDialog.setSize(580, 480);
 386  0
                         dialogPanel = new VerticalPanel();
 387  0
                         submitSuccessDialog.setWidget(dialogPanel);
 388  
                         
 389  
                 }
 390  
 
 391  0
         }
 392  
         
 393  
         private void setupDialog(){
 394  
 
 395  0
                 dialog.getConfirmButton().addClickHandler(new ClickHandler(){
 396  
 
 397  
                         @Override
 398  
                         public void onClick(ClickEvent event) {
 399  0
                                 dialog.getConfirmButton().setEnabled(false);
 400  0
                                 workflowRpcServiceAsync.submitDocumentWithId(workflowId, new KSAsyncCallback<Boolean>(){
 401  
                                         @Override
 402  
                     public void handleFailure(Throwable caught) {
 403  0
                                                 Window.alert("Error starting Proposal workflow");
 404  0
                                                 dialog.getConfirmButton().setEnabled(true);
 405  0
                                         }
 406  
                                         public void onSuccess(Boolean result) {
 407  0
                                                 if (result){
 408  0
                                                         updateWorkflow(dataModel);                                                
 409  0
                                                         dialog.hide();
 410  0
                                                         dialog.getConfirmButton().setEnabled(true);
 411  0
                                                         if(submitCallback != null){
 412  0
                                                                 submitCallback.exec(true);
 413  
                                                         }
 414  
                                                         //Notify the user that the document was submitted
 415  0
                                                         KSNotifier.add(new KSNotification("Proposal has been routed to workflow", false));
 416  
                                                 } else {
 417  0
                                                         Window.alert("Error starting Proposal workflow");
 418  
                                                 }
 419  0
                                         }
 420  
                                 });
 421  
                                 
 422  0
                         }
 423  
                 });
 424  0
         }
 425  
         
 426  
         public Widget getWorkflowActionsWidget(){
 427  
                 //InfoMessage infoContainer = new InfoMessage();
 428  0
                 StylishDropDown workflowActionsDropDown = GWT.create(StylishDropDown.class);
 429  0
                 workflowActionsDropDown.initialise(dropDownLabel );
 430  0
                 workflowActionsDropDown.makeAButtonWhenOneItem(true);
 431  0
                 workflowActionsDropDown.addStyleName("KS-Workflow-DropDown");
 432  0
                 workflowWidgets.add(workflowActionsDropDown);
 433  0
                 workflowActionsDropDown.setVisible(false);
 434  0
                 updateWorkflow(dataModel);
 435  
 /*                infoContainer.add(workflowActionsDropDown);
 436  
                 infoContainer.showWarnStyling(false);
 437  
                 infoContainer.setVisible(true);*/
 438  
                 //workflowActionsDropDown
 439  0
                 return workflowActionsDropDown;
 440  
         }
 441  
         
 442  
     public void enableWorkflowActionsWidgets(boolean enable) {
 443  0
         workflowWidgetsEnabled = enable;
 444  0
                 updateWorkflowActionsWidget();
 445  0
         }
 446  
         
 447  
     //callback is returned a List<ValidationResultInfo> result through the callback's exec
 448  
         public void doValidationCheck(Callback<List<ValidationResultInfo>> callback){
 449  0
                 dataModel.validateNextState(callback);
 450  0
         }
 451  
         
 452  
         public KSLabel getWorkflowStatusLabel(){
 453  0
                 return workflowStatusLabel;
 454  
         }
 455  
         
 456  
     public KSLabel getProposalStatusLabel() {
 457  0
         return proposalStatusLabel;
 458  
     }
 459  
 
 460  
     private void updateWorkflowIdFromModel(final DataModel model) {
 461  0
                 if(model!=null){
 462  0
                         String modelProposalId = model.get(QueryPath.parse(proposalPath + "/id"));
 463  
                         
 464  
                         //If proposalId in model has been set or changed, get new workflowId and update workflow widget
 465  0
                         if (modelProposalId != null && !modelProposalId.isEmpty() && !modelProposalId.equals(proposalId)){
 466  0
                                 proposalId = modelProposalId;
 467  0
                                 workflowId = model.get(QueryPath.parse(proposalPath + "/workflowId"));
 468  0
                                 proposalName = model.get(QueryPath.parse(proposalPath + "/name"));
 469  
                         }
 470  
                 }
 471  0
         }
 472  
 
 473  
         private void updateWorkflow(DataModel model){
 474  0
                 updateWorkflowIdFromModel(model);
 475  
                 
 476  0
                 if (workflowId != null && !workflowId.isEmpty()){
 477  
                         //Determine which workflow actions are displayed in the drop down
 478  0
                         workflowRpcServiceAsync.getActionsRequested(workflowId, new KSAsyncCallback<String>(){
 479  
                 
 480  
                                 public void onSuccess(String result) {
 481  0
                                         workflowActions = result;
 482  0
                                         updateWorkflowActionsWidget();
 483  0
                                 }
 484  
                         });
 485  
                 
 486  0
                         workflowRpcServiceAsync.getDocumentStatus(workflowId, new KSAsyncCallback<String>(){
 487  
                                 @Override
 488  
                                 public void handleFailure(Throwable caught) {
 489  0
                     setWorkflowStatus("Unknown");
 490  0
                                 }
 491  
 
 492  
                                 @Override
 493  
                                 public void onSuccess(String result) {
 494  0
                                         setWorkflowStatus(result);
 495  0
                                 }                                                
 496  
                         });
 497  0
             proposalServiceAsync.getProposalByWorkflowId(workflowId, new KSAsyncCallback<ProposalInfo>() {
 498  
                 @Override
 499  
                 public void handleFailure(Throwable caught) {
 500  0
                     setProposalStatus("Unknown");
 501  0
                 }
 502  
 
 503  
                 @Override
 504  
                 public void onSuccess(ProposalInfo result) {
 505  0
                     setProposalStatus(result.getState());
 506  0
                 }
 507  
             });
 508  
                 } else {
 509  0
             setWorkflowStatus("Draft");
 510  0
             setProposalStatus("Draft");
 511  
                 }                        
 512  0
         }
 513  
         
 514  
         private void updateWorkflowActionsWidget(){
 515  0
                 items.clear();
 516  
 
 517  
                 //When workflow widgets enabled display all available actions, otherwise only
 518  
                 //display Cancel, Acknowledge, FYI and Withdraw actions.
 519  0
                 if (workflowWidgetsEnabled){
 520  
                 //Get the workflowNode from the proposal
 521  0
                         String workflowNode = null;
 522  0
                 if(dataModel!=null){
 523  0
                         workflowNode = dataModel.get("proposal/workflowNode");
 524  
                 }
 525  
                 
 526  0
                         if(workflowActions.contains("S")){
 527  0
                                 items.add(wfStartWorkflowItem);
 528  
                         }
 529  0
             if(workflowActions.contains("C")){
 530  0
                 items.add(wfCancelWorkflowItem);
 531  
             }
 532  0
                         if(workflowActions.contains("A")){
 533  0
                                 items.add(wfApproveItem);
 534  
                                 //Change the approve label  to resubmit if it is the first node
 535  0
                                 if("PreRoute".equals(workflowNode)){
 536  0
                                     wfApproveItem.setLabel("Resubmit Proposal");
 537  
                     }else{
 538  0
                                     wfApproveItem.setLabel("Approve Proposal");
 539  
                                     //Only add disapprove if it is not the first node
 540  0
                                     items.add(wfDisApproveItem);
 541  
                     }
 542  
                         }
 543  0
                         if(workflowActions.contains("K")){
 544  0
                                 items.add(wfAcknowledgeItem);
 545  
                         }
 546  0
                         if(workflowActions.contains("F")){
 547  0
                                 items.add(wfFYIWorkflowItem);
 548  
                         }
 549  0
             if(workflowActions.contains("R")){
 550  
                     //Don't show the return to previous if this is already in preroute.
 551  
                     //Why is this showing up in WF actions?
 552  0
                     if(!"PreRoute".equals(workflowNode)){
 553  0
                             items.add(wfReturnToPreviousItem);
 554  
                     }
 555  
             }
 556  0
             if(workflowActions.contains("B")){
 557  0
                 items.add(wfBlanketApproveItem);
 558  
             }
 559  0
             if(workflowActions.contains("W")){
 560  0
                 items.add(wfWithdrawItem);
 561  
             }
 562  0
                 } else {                        
 563  0
             if(workflowActions.contains("C")){
 564  0
                 items.add(wfCancelWorkflowItem);
 565  
             }
 566  0
                         if(workflowActions.contains("K")){
 567  0
                                 items.add(wfAcknowledgeItem);
 568  
                         }
 569  0
                         if(workflowActions.contains("F")){
 570  0
                                 items.add(wfFYIWorkflowItem);
 571  
                         }            
 572  0
             if(workflowActions.contains("W")){
 573  0
                 items.add(wfWithdrawItem);
 574  
             }
 575  0
             if(workflowActions.contains("A")){
 576  0
                 items.add(wfDisApproveItem);               
 577  
             }
 578  
                 }
 579  
 
 580  
                 //Add in any other custom items you want in this dropdown.
 581  0
                 items.addAll(additionalItems);
 582  
                 
 583  0
                 for(StylishDropDown widget: workflowWidgets){
 584  
                         
 585  0
                         widget.setItems(items);
 586  0
                         widget.setEnabled(true);
 587  0
                         if(items.isEmpty()){
 588  0
                                 widget.setVisible(false);
 589  
                         }
 590  
                         else{
 591  0
                                 widget.setVisible(true);
 592  
                         }
 593  
                 }                
 594  0
         }
 595  
         
 596  
         private KSMenuItemData getFYIWorkflowItem() {
 597  
                 KSMenuItemData wfFYIWorkflowItem;
 598  0
                 final KSRichEditor rationaleEditor = new KSRichEditor();
 599  0
                 wfFYIWorkflowItem = new KSMenuItemData("FYI Proposal", new ClickHandler(){
 600  
                 public void onClick(ClickEvent event) {           
 601  0
                         addRationale(rationaleEditor,DecisionRationaleDetail.FYI.getType());
 602  0
                                 workflowRpcServiceAsync.fyiDocumentWithId(workflowId, new KSAsyncCallback<Boolean>(){
 603  
                                         @Override
 604  
                     public void handleFailure(Throwable caught) {
 605  0
                                                 Window.alert("Error FYIing Proposal");
 606  0
                                         }
 607  
                                         public void onSuccess(
 608  
                                                         Boolean result) {
 609  0
                                                 if(result){
 610  0
                                                         updateWorkflow(dataModel);
 611  0
                                                         if(submitCallback != null){
 612  0
                                                                 submitCallback.exec(true);
 613  
                                                         }
 614  
                                                         //Notify the user that the document was FYIed
 615  0
                                                         KSNotifier.add(new KSNotification("Proposal was FYIed", false));
 616  
                                                 }else{
 617  0
                                                         Window.alert("Error FYIing Proposal");
 618  
                                                 }
 619  0
                                         }
 620  
                                         
 621  
                                 });
 622  0
                 }        
 623  
             });
 624  0
                 return wfFYIWorkflowItem;
 625  
         }
 626  
 
 627  
         private KSMenuItemData getAcknowledgeItem() {
 628  
                 KSMenuItemData wfAcknowledgeItem;
 629  0
                 wfAcknowledgeItem = new KSMenuItemData("Acknowledge Proposal", new ClickHandler(){
 630  
                 public void onClick(ClickEvent event) {
 631  0
                         setupSubmitSuccessDialog();
 632  0
                                 final KSRichEditor rationaleEditor = new KSRichEditor();
 633  0
                                 final AcknowledgeCancelGroup approvalButton = new AcknowledgeCancelGroup(new Callback<AcknowledgeCancelEnum>(){
 634  
 
 635  
                                         @Override
 636  
                                         public void exec(AcknowledgeCancelEnum result) {
 637  0
                                                 if(!result.name().equals("CANCEL")){
 638  0
                                                         addRationale(rationaleEditor,DecisionRationaleDetail.ACKNOWLEDGE.getType());
 639  0
                                                         workflowRpcServiceAsync.acknowledgeDocumentWithId(workflowId, new KSAsyncCallback<Boolean>(){
 640  
                                                                 @Override
 641  
                                 public void handleFailure(Throwable caught) {
 642  0
                                                                         submitSuccessDialog.hide();
 643  0
                                                                         Window.alert("Error acknowledging Proposal");
 644  0
                                                                 }
 645  
                                                                 public void onSuccess(Boolean result) {
 646  0
                                                                         submitSuccessDialog.hide();
 647  0
                                                                         if(result){
 648  0
                                                                                 updateWorkflow(dataModel);
 649  0
                                                                                 if(submitCallback != null){
 650  0
                                                                                         submitCallback.exec(true);
 651  
                                                                                 }
 652  
                                                                                 //Notify the user that the document was acknowledged
 653  0
                                                                                 KSNotifier.add(new KSNotification("Proposal was acknowledged", false));
 654  
                                                                         }else{
 655  0
                                                                                 Window.alert("Error acknowledging Proposal");
 656  
                                                                         }
 657  0
                                                                 }
 658  
                                                         });
 659  
                                                 }
 660  
                                                 else{
 661  0
                                                         submitSuccessDialog.hide();
 662  
                                                 }
 663  0
                                         }
 664  
                                 });
 665  
                                 
 666  0
                                 approvalButton.getButton(ButtonEnumerations.AcknowledgeCancelEnum.ACKNOWLEDGE).setEnabled(false);
 667  
                 
 668  0
                 rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 669  
 
 670  
                     @Override
 671  
                     public void onKeyUp(KeyUpEvent event) {
 672  0
                         if(!rationaleEditor.getText().trim().isEmpty()){
 673  0
                             approvalButton.getButton(ButtonEnumerations.AcknowledgeCancelEnum.ACKNOWLEDGE).setEnabled(true);
 674  
                         } else {
 675  0
                             approvalButton.getButton(ButtonEnumerations.AcknowledgeCancelEnum.ACKNOWLEDGE).setEnabled(false);
 676  
                         }                            
 677  0
                     }
 678  
                     
 679  
                 });
 680  
                                 
 681  0
                                 SectionTitle headerTitle = SectionTitle.generateH3Title("Acknowledge Proposal");
 682  0
                                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are acknowledging the " + proposalName +" proposal");
 683  0
                                 SectionTitle fieldLabel = SectionTitle.generateH4Title("Decision Rationale");
 684  0
                                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 685  0
                                 dialogPanel.clear();
 686  0
                                 submitSuccessDialog.clearButtons();
 687  0
                                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 688  0
                                 dialogPanel.add(dialogLabel);
 689  0
                                 dialogPanel.add(fieldLabel);
 690  0
                                 dialogPanel.add(rationaleEditor);
 691  0
                                 submitSuccessDialog.addButtonGroup(approvalButton);
 692  0
                                 submitSuccessDialog.show();
 693  0
                 }        
 694  
             });
 695  0
                 return wfAcknowledgeItem;
 696  
         }
 697  
 
 698  
         private KSMenuItemData getDisApproveItem() {
 699  
                 KSMenuItemData wfDisApproveItem;
 700  0
                 wfDisApproveItem = new KSMenuItemData("Reject Proposal", new ClickHandler(){
 701  
                 public void onClick(ClickEvent event) {   
 702  0
                         setupSubmitSuccessDialog();
 703  0
                                 final KSRichEditor rationaleEditor = new KSRichEditor();
 704  
                                 
 705  0
                                 final RejectCancelGroup disapprovalButton = new RejectCancelGroup(new Callback<RejectCancelEnum>(){
 706  
 
 707  
                                         @Override
 708  
                                         public void exec(RejectCancelEnum result) {
 709  0
                                                 if(!result.name().equals("CANCEL")){
 710  0
                                                         if(rationaleEditor.getText().trim().equals("")){
 711  0
                                                                 required.setText("Please enter the decision rationale");
 712  
                                                         }
 713  
                                                         else{
 714  0
                                                                 addRationale(rationaleEditor,DecisionRationaleDetail.REJECT.getType());
 715  0
                                                                 workflowRpcServiceAsync.disapproveDocumentWithId(workflowId, new KSAsyncCallback<Boolean>(){
 716  
                                                                         @Override
 717  
                                     public void handleFailure(Throwable caught) {
 718  0
                                                                                 submitSuccessDialog.hide();
 719  0
                                                                                 Window.alert("Error rejecting Proposal");
 720  0
                                                                         }
 721  
                                                                         public void onSuccess(Boolean result) {
 722  0
                                                                                 submitSuccessDialog.hide();
 723  0
                                                                                 if(submitCallback != null){
 724  0
                                                                                         submitCallback.exec(result);
 725  
                                                                                 }
 726  0
                                                                                 if(result){
 727  0
                                                                                         KSNotifier.add(new KSNotification("Proposal was rejected", false));
 728  0
                                                                                         updateWorkflow(dataModel);
 729  
                                                                                 }else{
 730  0
                                                                                         Window.alert("Error rejecting Proposal");
 731  
                                                                                 }
 732  0
                                                                         }
 733  
                                                                         
 734  
                                                                 });
 735  
                                                         }
 736  
 
 737  
                                         }
 738  
                                         else{
 739  0
                                                 submitSuccessDialog.hide();
 740  
                                         }
 741  0
                                         }
 742  
                                 });
 743  
                                 
 744  0
                                 disapprovalButton.getButton(ButtonEnumerations.RejectCancelEnum.REJECT).setEnabled(false);
 745  
                                 
 746  0
                 rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 747  
 
 748  
                     @Override
 749  
                     public void onKeyUp(KeyUpEvent event) {
 750  0
                         if(!rationaleEditor.getText().trim().isEmpty()){
 751  0
                             disapprovalButton.getButton(ButtonEnumerations.RejectCancelEnum.REJECT).setEnabled(true);
 752  
                         } else {
 753  0
                             disapprovalButton.getButton(ButtonEnumerations.RejectCancelEnum.REJECT).setEnabled(false);
 754  
                         }                            
 755  0
                     }
 756  
                     
 757  
                 });
 758  
                                 
 759  0
                                 SectionTitle headerTitle = SectionTitle.generateH3Title("Reject Proposal");
 760  0
                                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are rejecting the " + proposalName +" proposal");
 761  0
                                 SectionTitle fieldLabel = SectionTitle.generateH4Title("Decision Rationale");
 762  0
                                 required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 763  0
                                 required.setVisible(true);
 764  
 //                                final KSRichEditor rationaleEditor = new KSRichEditor();
 765  
 //                                rationaleEditor.addStyleName("ks-textarea-width");
 766  
 //                                rationaleEditor.addStyleName("ks-textarea-large-height");
 767  0
                                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 768  0
                                 dialogPanel.clear();
 769  0
                                 submitSuccessDialog.clearButtons();
 770  0
                                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 771  0
                                 dialogPanel.add(dialogLabel);
 772  0
                                 dialogPanel.add(fieldLabel);
 773  0
                                 dialogPanel.add(required);
 774  0
                                 dialogPanel.add(rationaleEditor);
 775  0
                                 submitSuccessDialog.addButtonGroup(disapprovalButton);
 776  0
                                 submitSuccessDialog.setWidget(dialogPanel);
 777  0
                                 submitSuccessDialog.show();
 778  0
                 }        
 779  
             });
 780  0
                 return wfDisApproveItem;
 781  
         }
 782  
 
 783  
         private KSMenuItemData getApproveItem() {
 784  
                 KSMenuItemData wfApproveItem;
 785  
                 
 786  0
                 wfApproveItem= new KSMenuItemData("Approve Proposal", new ClickHandler(){
 787  
                         public void onClick(ClickEvent event) {
 788  0
                                 setupSubmitSuccessDialog();
 789  0
                                 final KSRichEditor rationaleEditor = new KSRichEditor();
 790  
                                 
 791  
 //                                final ActionCancelGroup approveCancelButtons = new ActionCancelGroup(ButtonEnumerations.ApproveCancelEnum.APPROVE, ButtonEnumerations.ApproveCancelEnum.CANCEL);                                  
 792  
                                                   
 793  0
                                 approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(false);
 794  
                                 
 795  0
                                 approveCancelButtons.addCallback(new Callback<ButtonEnumerations.ButtonEnum>() {
 796  
                     @Override
 797  
                     public void exec(ButtonEnumerations.ButtonEnum result) {
 798  0
                         if (result != ButtonEnumerations.ApproveCancelEnum.CANCEL) {
 799  0
                             if (rationaleEditor.getText().trim().equals("")) {
 800  0
                                 required.setText("Please enter the decision rationale");
 801  
                             } else {
 802  0
                                 if (approveDialogView != null) {
 803  
                                     // Validate all the fields on the current section (the additional required fields)
 804  0
                                     parentController.requestModel(new ModelRequestCallback<DataModel>() {
 805  
 
 806  
                                         @Override
 807  
                                         public void onModelReady(DataModel model) {
 808  0
                                             approveDialogView.updateModel();
 809  0
                                             model.validateNextState(new Callback<List<ValidationResultInfo>>() {
 810  
                                                 @Override
 811  
                                                 public void exec(List<ValidationResultInfo> results) {
 812  
                                                     // Process the results on the additional fields view
 813  0
                                                     if (ErrorLevel.OK.equals(approveDialogView.processValidationResults(results))) {
 814  
                                                         // Save first and then do the workflow actions later
 815  0
                                                         SaveActionEvent saveActionEvent = new SaveActionEvent();
 816  0
                                                         saveActionEvent.setActionCompleteCallback(new ActionCompleteCallback() {
 817  
                                                             public void onActionComplete(ActionEvent action) {
 818  0
                                                                 doWorkflowApprove();
 819  0
                                                             }
 820  
                                                         });
 821  0
                                                         parentController.fireApplicationEvent(saveActionEvent);
 822  0
                                                     } else {
 823  0
                                                         KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
 824  
                                                     }
 825  0
                                                 }
 826  
                                             });
 827  0
                                         }
 828  
 
 829  
                                         @Override
 830  
                                         public void onRequestFail(Throwable cause) {
 831  0
                                             KSNotifier.add(new KSNotification("Error requesting data model.", false, true, 5000));
 832  0
                                         }
 833  
 
 834  
                                     });
 835  
 
 836  
                                 } else {
 837  0
                                     doWorkflowApprove();
 838  
                                 }
 839  
 
 840  
                             }
 841  
 
 842  
                         } else {
 843  0
                             submitSuccessDialog.hide();
 844  
                         }
 845  0
                     }
 846  
 
 847  
                     private void doWorkflowApprove() {
 848  0
                         addRationale(rationaleEditor, DecisionRationaleDetail.APPROVE.getType());
 849  
 
 850  0
                         workflowRpcServiceAsync.approveDocumentWithId(workflowId, new KSAsyncCallback<Boolean>() {
 851  
                             @Override
 852  
                             public void handleFailure(Throwable caught) {
 853  0
                                 submitSuccessDialog.hide();
 854  0
                                 Window.alert("Error approving Proposal");
 855  0
                             }
 856  
 
 857  
                             public void onSuccess(Boolean result) {
 858  0
                                 submitSuccessDialog.hide();
 859  0
                                 if (result) {
 860  0
                                     updateWorkflow(dataModel);
 861  0
                                     if (submitCallback != null) {
 862  0
                                         submitCallback.exec(result);
 863  
                                     }
 864  
                                     // Notify the user that the document was approved
 865  0
                                     KSNotifier.add(new KSNotification("Proposal was approved", false));
 866  
                                 } else {
 867  0
                                     Window.alert("Error approving Proposal");
 868  
                                 }
 869  0
                             }
 870  
                         });
 871  
 
 872  0
                     }
 873  
                 });                                
 874  
 
 875  0
                 if(approveDialogView.getField("proposal/prevEndTerm") != null){                    
 876  
                     
 877  0
                     approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(false);                    
 878  0
                     rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 879  
 
 880  
                         @Override
 881  
                         public void onKeyUp(KeyUpEvent event) {
 882  0
                             if(!rationaleEditor.getText().trim().isEmpty() && !(((KSPicker) (approveDialogView.getField("proposal/prevEndTerm").getFieldWidget())).getDisplayValue() == "") ){
 883  0
                                 approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(true);
 884  
                             } else {
 885  0
                                 approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(false);
 886  
                             }                            
 887  0
                         }
 888  
                         
 889  
                     });     
 890  
                     
 891  0
                     if (approveDialogView.getField("proposal/prevEndTerm").getFieldWidget() instanceof KSPicker) {
 892  0
                             ((KSPicker) (approveDialogView.getField("proposal/prevEndTerm").getFieldWidget())).addSelectionChangeHandler(new SelectionChangeHandler(){
 893  
 
 894  
                             @Override
 895  
                             public void onSelectionChange(SelectionChangeEvent event) {
 896  0
                                 if(!rationaleEditor.getText().trim().isEmpty() && !(((KSPicker) (approveDialogView.getField("proposal/prevEndTerm").getFieldWidget())).getDisplayValue() == "")  ){
 897  0
                                     approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(true);
 898  
                                 } else {
 899  0
                                     approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(false);
 900  
                                 }
 901  0
                             }
 902  
 
 903  
                         });
 904  
                     }
 905  
                 } else {
 906  
                     
 907  0
                     rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 908  
 
 909  
                         @Override
 910  
                         public void onKeyUp(KeyUpEvent event) {
 911  0
                             if(!rationaleEditor.getText().trim().isEmpty()){
 912  0
                                 approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(true);
 913  
                             } else {
 914  0
                                 approveCancelButtons.getButton(ButtonEnumerations.ApproveCancelEnum.APPROVE).setEnabled(false);
 915  
                             }                            
 916  0
                         }
 917  
                         
 918  
                     }); 
 919  
                     
 920  
                 }
 921  
                                 
 922  0
                                 SectionTitle headerTitle = SectionTitle.generateH3Title("Approve Proposal");
 923  0
                                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are approving the " + proposalName +" proposal");
 924  0
                                 SectionTitle fieldLabel = SectionTitle.generateH4Title("Decision Rationale");                                
 925  0
                                 required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 926  0
                                 required.setVisible(true);                                
 927  0
                 HorizontalPanel rationalePanel = new HorizontalPanel();                
 928  0
                 rationalePanel.add(fieldLabel);
 929  0
                 rationalePanel.add(required);                                
 930  0
                                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 931  0
                                 dialogPanel.clear();
 932  0
                                 submitSuccessDialog.clearButtons();
 933  0
                                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 934  0
                                 dialogPanel.add(dialogLabel);
 935  0
                                 dialogPanel.add(rationalePanel);
 936  0
                                 dialogPanel.add(rationaleEditor);
 937  0
                 if(approveDialogView!=null && !approveDialogView.getFields().isEmpty()){
 938  0
                         dialogPanel.add(approveDialogView.asWidget());
 939  
                 }
 940  0
                                 submitSuccessDialog.addButtonGroup(approveCancelButtons);
 941  
                                 //dialogPanel.setSize("580px", "450px");
 942  0
                                 dialogPanel.setHeight("380px");
 943  0
                                 submitSuccessDialog.show();
 944  0
                         }        
 945  
                 });
 946  0
                 return wfApproveItem;
 947  
         }
 948  
 
 949  
     private KSMenuItemData getWithdrawItem() {
 950  
         KSMenuItemData wfWithdrawItem;
 951  
 
 952  0
         wfWithdrawItem = new KSMenuItemData("Withdraw Proposal", new ClickHandler() {
 953  
             public void onClick(ClickEvent event) {
 954  0
                 setupSubmitSuccessDialog();
 955  0
                 final KSRichEditor rationaleEditor = new KSRichEditor();
 956  0
                 final ConfirmCancelGroup withdrawButton = new ConfirmCancelGroup(new Callback<ConfirmCancelEnum>() {
 957  
 
 958  
                     @Override
 959  
                     public void exec(ConfirmCancelEnum result) {
 960  0
                         if (!result.name().equals("CANCEL")) {
 961  0
                             if (rationaleEditor.getText().trim().equals("")) {
 962  0
                                 required.setText("Please enter the decision rationale");
 963  
                             } else {
 964  0
                                 addRationale(rationaleEditor, DecisionRationaleDetail.WITHDRAW.getType());
 965  
 
 966  0
                                 workflowRpcServiceAsync.withdrawDocumentWithId(workflowId, new KSAsyncCallback<Boolean>() {
 967  
                                     @Override
 968  
                                     public void handleFailure(Throwable caught) {
 969  0
                                         submitSuccessDialog.hide();
 970  0
                                         Window.alert("Error withdrawing Proposal");
 971  0
                                     }
 972  
 
 973  
                                     public void onSuccess(Boolean result) {
 974  0
                                         submitSuccessDialog.hide();
 975  0
                                         if (result) {
 976  0
                                             updateWorkflow(dataModel);
 977  0
                                             if (submitCallback != null) {
 978  0
                                                 submitCallback.exec(result);
 979  
                                             }
 980  
                                             // Notify the user that the document was approved
 981  0
                                             KSNotifier.add(new KSNotification("Proposal will be withdrawn", false));
 982  
                                         } else {
 983  0
                                             Window.alert("Error withdrawing Proposal");
 984  
                                         }
 985  0
                                     }
 986  
                                 });
 987  
                             }
 988  
 
 989  
                         } else {
 990  0
                             submitSuccessDialog.hide();
 991  
                         }
 992  0
                     }
 993  
                 });
 994  
                 
 995  0
                 withdrawButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 996  
                 
 997  0
                 rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 998  
 
 999  
                     @Override
 1000  
                     public void onKeyUp(KeyUpEvent event) {
 1001  0
                         if(!rationaleEditor.getText().trim().isEmpty()){
 1002  0
                             withdrawButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(true);
 1003  
                         } else {
 1004  0
                             withdrawButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1005  
                         }                            
 1006  0
                     }
 1007  
                     
 1008  
                 });      
 1009  
                 
 1010  
 
 1011  0
                 SectionTitle headerTitle = SectionTitle.generateH3Title("Withdraw Proposal");
 1012  0
                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are withdrawing the " + proposalName + " proposal");
 1013  0
                 SectionTitle fieldLabel = SectionTitle.generateH4Title("Decision Rationale");
 1014  0
                 required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 1015  0
                 required.setVisible(true);
 1016  0
                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 1017  0
                 dialogPanel.clear();
 1018  0
                 submitSuccessDialog.clearButtons();
 1019  0
                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 1020  0
                 dialogPanel.add(dialogLabel);
 1021  0
                 dialogPanel.add(fieldLabel);
 1022  0
                 dialogPanel.add(required);
 1023  0
                 dialogPanel.add(rationaleEditor);
 1024  0
                 submitSuccessDialog.addButtonGroup(withdrawButton);
 1025  
                 //dialogPanel.setSize("580px", "400px");
 1026  0
                 dialogPanel.setHeight("380px");
 1027  
                 // submitSuccessDialog.setWidget(dialogPanel);
 1028  0
                 submitSuccessDialog.show();
 1029  0
             }
 1030  
         });
 1031  0
         return wfWithdrawItem;
 1032  
     }
 1033  
 
 1034  
     private KSMenuItemData getBlanketApproveItem() {
 1035  
         KSMenuItemData wfBlanketApproveItem;
 1036  
 
 1037  0
         wfBlanketApproveItem = new KSMenuItemData("Blanket Approve Proposal", new ClickHandler() {
 1038  
             public void onClick(ClickEvent event) {
 1039  0
                 setupSubmitSuccessDialog();
 1040  0
                 final KSRichEditor rationaleEditor = new KSRichEditor();
 1041  0
                 final ConfirmCancelGroup blanketApprovalButton = new ConfirmCancelGroup(new Callback<ConfirmCancelEnum>() {
 1042  
 
 1043  
                     @Override
 1044  
                     public void exec(ConfirmCancelEnum result) {
 1045  0
                         if (!result.name().equals("CANCEL")) {
 1046  0
                             if (rationaleEditor.getText().trim().equals("")) {
 1047  0
                                 required.setText("Please enter the decision rationale");
 1048  
                             } else {
 1049  
                                     
 1050  0
                                                                 if(blanketApproveDialogView!=null){
 1051  
                                                                         //Validate all the fields on the current section (the additional required fields)
 1052  0
                                                                         parentController.requestModel(new ModelRequestCallback<DataModel>(){
 1053  
 
 1054  
                                                                                 @Override
 1055  
                                                                                 public void onModelReady(final DataModel model) {
 1056  0
                                                                                         blanketApproveDialogView.updateModel();
 1057  0
                                                                                         if(parentController instanceof WorkflowEnhancedNavController){
 1058  0
                                                                                                 ((WorkflowEnhancedNavController)parentController).getMetadataForFinalState(new KSAsyncCallback<Metadata>(){
 1059  
 
 1060  
                                                                                                         @Override
 1061  
                                                                                                         public void onSuccess(
 1062  
                                                                                                                         Metadata metadata) {
 1063  0
                                                                                                                 model.validateForMetadata(metadata, new Callback<List<ValidationResultInfo>>() {
 1064  
                                                                                                     @Override
 1065  
                                                                                                     public void exec(List<ValidationResultInfo> results) {
 1066  
                                                                                                             //first validate the dialog section
 1067  
                                                                                                             
 1068  
                                                                                                             //Process the results on the additional fields view
 1069  
                                                                                                             
 1070  0
                                                                                                             if(ErrorLevel.OK.equals(blanketApproveDialogView.processValidationResults(results))){
 1071  0
                                                                                                                     List<String> ignoreFields = new ArrayList<String>(ignoredApproveDialogFields);
 1072  0
                                                                                                                     for(FieldDescriptor fd:blanketApproveDialogView.getFields()){
 1073  0
                                                                                                                             ignoreFields.add(fd.getFieldKey());
 1074  
                                                                                                                     }
 1075  0
                                                                                                                     if(!ValidationResultInfo.hasValidationErrors(results,ErrorLevel.WARN,ignoreFields)){
 1076  
                                                                                                                                                 //Save first and then do the workflow actions later
 1077  0
                                                                                                                                                 SaveActionEvent saveActionEvent = new SaveActionEvent();
 1078  0
                                                                                                                                 saveActionEvent.setActionCompleteCallback(new ActionCompleteCallback(){
 1079  
                                                                                                                                     public void onActionComplete(ActionEvent action) {
 1080  0
                                                                                                                                             doBlanketApprove();
 1081  0
                                                                                                                                     }
 1082  
                                                                                                                                 });
 1083  0
                                                                                                                                 parentController.fireApplicationEvent(saveActionEvent);
 1084  0
                                                                                                                     }else{
 1085  0
                                                                                                                         submitSuccessDialog.hide();
 1086  0
                                                                                                                             KSNotifier.add(new KSNotification("Unable to blanket approve, please enter all data required for final approval.", false, true, 5000));
 1087  
                                                                                                                     }
 1088  0
                                                                                                             }else{
 1089  0
                                                                                                                     KSNotifier.add(new KSNotification("Unable to blanket approve, please enter all data required for final approval.", false, true, 5000));
 1090  
                                                                                                             }
 1091  0
                                                                                                     }
 1092  
                                                                                                                 });
 1093  0
                                                                                                         }
 1094  
                                                                                                         
 1095  
                                                                                                 });
 1096  
                                                                                         }
 1097  0
                                                                                 }
 1098  
 
 1099  
                                                                                 @Override
 1100  
                                                                                 public void onRequestFail(
 1101  
                                                                                                 Throwable cause) {
 1102  0
                                                                                         KSNotifier.add(new KSNotification("Error requesting data model.", false, true, 5000));
 1103  0
                                                                                 }
 1104  
                                                                                 
 1105  
                                                                         });
 1106  
 
 1107  
                                                                 }else{
 1108  0
                                                                         doBlanketApprove();
 1109  
                                                                 }
 1110  
                                     
 1111  
            
 1112  
                             }
 1113  
                         } else {
 1114  0
                             submitSuccessDialog.hide();
 1115  0
                             updateWorkflowActionsWidget();
 1116  
                         }
 1117  0
                     }
 1118  
 
 1119  
                                         private void doBlanketApprove() {
 1120  0
                         addRationale(rationaleEditor, DecisionRationaleDetail.BLANKET_APPROVE.getType());
 1121  0
                         workflowRpcServiceAsync.blanketApproveDocumentWithId(workflowId, new KSAsyncCallback<Boolean>() {
 1122  
                             @Override
 1123  
                             public void handleFailure(Throwable caught) {
 1124  0
                                             submitSuccessDialog.hide();
 1125  0
                                 Window.alert("Error blanket approving Proposal");
 1126  0
                             }
 1127  
 
 1128  
                             public void onSuccess(Boolean result) {
 1129  0
                                             submitSuccessDialog.hide();
 1130  0
                                 if (result) {
 1131  
                                     // KSLAB-1828; we get "B" back from workflowRpcServiceAsync.getActionsRequested()
 1132  
                                     // even though we just successfully submitted blanket approval to workflow,
 1133  
                                     // because the workflow action hasn't been completed yet.
 1134  0
                                     enableWorkflowActionsWidgets(false);
 1135  
 
 1136  0
                                     updateWorkflow(dataModel);
 1137  0
                                     if (submitCallback != null) {
 1138  0
                                         submitCallback.exec(result);
 1139  
                                     }
 1140  
                                     // Notify the user that the document was approved
 1141  0
                                     KSNotifier.add(new KSNotification("Proposal will be blanket approved", false));
 1142  
                                 } else {
 1143  0
                                     Window.alert("Error blanket approving Proposal");
 1144  
                                 }
 1145  0
                             }
 1146  
                         }); 
 1147  0
                                         }
 1148  
                 });
 1149  
                 
 1150  0
                 blanketApprovalButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1151  
                 
 1152  0
                 rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 1153  
 
 1154  
                     @Override
 1155  
                     public void onKeyUp(KeyUpEvent event) {
 1156  0
                         if(!rationaleEditor.getText().trim().isEmpty()){
 1157  0
                             blanketApprovalButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(true);
 1158  
                         } else {
 1159  0
                             blanketApprovalButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1160  
                         }                            
 1161  0
                     }
 1162  
                     
 1163  
                 }); 
 1164  
 
 1165  0
                 SectionTitle headerTitle = SectionTitle.generateH3Title("Blanket Approve Proposal");
 1166  0
                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are blanket approving the " + proposalName + " proposal");
 1167  0
                 SectionTitle fieldLabel = SectionTitle.generateH4Title("Decision Rationale");
 1168  0
                 required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 1169  0
                 required.setVisible(true);
 1170  0
                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 1171  0
                 dialogPanel.clear();
 1172  0
                 submitSuccessDialog.clearButtons();
 1173  0
                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 1174  0
                 dialogPanel.add(dialogLabel);
 1175  0
                 dialogPanel.add(fieldLabel);
 1176  0
                 dialogPanel.add(required);
 1177  0
                 dialogPanel.add(rationaleEditor);
 1178  0
                 if(blanketApproveDialogView!=null && !blanketApproveDialogView.getFields().isEmpty()){
 1179  0
                         dialogPanel.add(blanketApproveDialogView.asWidget());
 1180  
                 }
 1181  0
                 submitSuccessDialog.addButtonGroup(blanketApprovalButton);
 1182  
                 //dialogPanel.setSize("580px", "400px");
 1183  0
                 dialogPanel.setHeight("380px");
 1184  
                 // submitSuccessDialog.setWidget(dialogPanel);
 1185  0
                 submitSuccessDialog.show();
 1186  0
             }
 1187  
         });
 1188  0
         return wfBlanketApproveItem;
 1189  
     }
 1190  
 
 1191  
     /**
 1192  
      * Call this method to blanked approve the workflow document associated with dataModel
 1193  
      * 
 1194  
      * 
 1195  
      * @param onSuccessCallback
 1196  
      */
 1197  
     public void blanketApprove(final Callback<Boolean> onSuccessCallback){
 1198  0
                    updateWorkflowIdFromModel(dataModel);
 1199  0
         workflowRpcServiceAsync.blanketApproveDocumentWithId(workflowId, new KSAsyncCallback<Boolean>() {
 1200  
             @Override
 1201  
             public void handleFailure(Throwable caught) {
 1202  0
                 Window.alert("Error blanket approving Proposal");
 1203  0
             }
 1204  
 
 1205  
             public void onSuccess(Boolean result) {
 1206  0
                 if (result) {
 1207  0
                         onSuccessCallback.exec(true);
 1208  
                 } else {
 1209  0
                     Window.alert("Error blanket approving Proposal");
 1210  
                 }
 1211  0
             }
 1212  
         });            
 1213  0
     }
 1214  
 
 1215  
     /**
 1216  
      * Call this method to cancel the workflow document associated with dataModel. User will be presented 
 1217  
      * with a confirmation dialog to confirm the cancellation of the proposal.
 1218  
      * 
 1219  
      * @param onSuccessCallback
 1220  
      */
 1221  
     public void cancel(final Callback<Boolean> onSuccessCallback){
 1222  0
             ConfirmationDialog confirmCancelDialog = getConfirmationCancelProposalDialog(onSuccessCallback);
 1223  0
             confirmCancelDialog.show();
 1224  0
     }
 1225  
 
 1226  
     
 1227  
     protected KSDropDown setUpReturnToPreviousDropDown(String workflowId) {
 1228  
 //        nodeNameList.clear();
 1229  0
         final KSDropDown nodeNameDropDown = new KSDropDown();
 1230  0
         nodeNameDropDown.setBlankFirstItem(true);
 1231  0
         workflowRpcServiceAsync.getPreviousRouteNodeNames(workflowId, new KSAsyncCallback<List<String>>() {
 1232  
             @Override
 1233  
             public void handleFailure(Throwable caught) {
 1234  0
                 Window.alert("Error getting previous node names for Proposal");
 1235  0
             }
 1236  
 
 1237  
             public void onSuccess(List<String> result) {
 1238  0
                 SimpleListItems nodeNameList = new SimpleListItems();
 1239  0
                 for (String nodeName : result) {
 1240  0
                     nodeNameList.addItem(nodeName, nodeName);
 1241  
                 }
 1242  0
                 nodeNameDropDown.setListItems(nodeNameList);
 1243  0
             }
 1244  
         });
 1245  0
         nodeNameDropDown.setInitialized(true);
 1246  0
         return nodeNameDropDown;
 1247  
     }
 1248  
 
 1249  
     private KSMenuItemData getReturnToPreviousItem() {
 1250  
         KSMenuItemData wfReturnToPreviousItem;
 1251  
 
 1252  0
         wfReturnToPreviousItem = new KSMenuItemData("Return Proposal to Previous Node", new ClickHandler() {
 1253  
             public void onClick(ClickEvent event) {
 1254  0
                 setupSubmitSuccessDialog();
 1255  0
                 final KSRichEditor rationaleEditor = new KSRichEditor();
 1256  0
                 final KSDropDown nodeNameDropDown = setUpReturnToPreviousDropDown(workflowId);
 1257  0
                 final ConfirmCancelGroup returnButton = new ConfirmCancelGroup(new Callback<ConfirmCancelEnum>() {
 1258  
 
 1259  
                     @Override
 1260  
                     public void exec(ConfirmCancelEnum result) {
 1261  0
                         if (!result.name().equals("CANCEL")) {
 1262  0
                             if ((rationaleEditor.getText().trim().equals("")) && (nodeNameDropDown.getSelectedItem()==null || nodeNameDropDown.getSelectedItem().trim().equals(""))) {
 1263  0
                                 required.setText("Please enter the decision rationale and select a node name to return to");
 1264  0
                             } else if (rationaleEditor.getText().trim().equals("")) {
 1265  0
                                 required.setText("Please enter the decision rationale");
 1266  0
                             } else if (nodeNameDropDown.getSelectedItem()==null || nodeNameDropDown.getSelectedItem().trim().equals("")) {
 1267  0
                                 required.setText("Please select a node name to return to");
 1268  
                             } else {
 1269  0
                                 addRationale(rationaleEditor, DecisionRationaleDetail.RETURN_TO_PREVIOUS.getType());
 1270  0
                                 String nodeName = nodeNameDropDown.getSelectedItem().trim();
 1271  0
                                 workflowRpcServiceAsync.returnDocumentWithId(workflowId, nodeName, new KSAsyncCallback<Boolean>() {
 1272  
                                     @Override
 1273  
                                     public void handleFailure(Throwable caught) {
 1274  0
                                         submitSuccessDialog.hide();
 1275  0
                                         Window.alert("Error returning the Proposal to a previous node");
 1276  0
                                     }
 1277  
 
 1278  
                                     public void onSuccess(Boolean result) {
 1279  0
                                         submitSuccessDialog.hide();
 1280  0
                                         if (result) {
 1281  0
                                             updateWorkflow(dataModel);
 1282  0
                                             if (submitCallback != null) {
 1283  0
                                                 submitCallback.exec(result);
 1284  
                                             }
 1285  
                                             // Notify the user that the document was approved
 1286  0
                                             KSNotifier.add(new KSNotification("Proposal was returned", false));
 1287  
                                         } else {
 1288  0
                                             Window.alert("Error returning the Proposal to a previous node");
 1289  
                                         }
 1290  0
                                     }
 1291  
                                 });
 1292  0
                             }
 1293  
 
 1294  
                         } else {
 1295  0
                             submitSuccessDialog.hide();
 1296  
                         }
 1297  0
                     }
 1298  
                 });
 1299  
                 
 1300  0
                 returnButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1301  
                 
 1302  0
                 rationaleEditor.getRichTextArea().addKeyUpHandler(new KeyUpHandler(){
 1303  
 
 1304  
                     @Override
 1305  
                     public void onKeyUp(KeyUpEvent event) {
 1306  0
                         if(!rationaleEditor.getText().trim().isEmpty() && !(nodeNameDropDown.getSelectedItem() == null)){
 1307  0
                             returnButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(true);
 1308  
                         } else {
 1309  0
                             returnButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1310  
                         }                            
 1311  0
                     }
 1312  
                     
 1313  
                 }); 
 1314  
                 
 1315  0
                 nodeNameDropDown.addSelectionChangeHandler(new SelectionChangeHandler(){
 1316  
 
 1317  
                     @Override
 1318  
                     public void onSelectionChange(SelectionChangeEvent event) {
 1319  0
                         if(!rationaleEditor.getText().trim().isEmpty() && !(nodeNameDropDown.getSelectedItem() == null)){
 1320  0
                             returnButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(true);
 1321  
                         } else {
 1322  0
                             returnButton.getButton(ButtonEnumerations.ConfirmCancelEnum.CONFIRM).setEnabled(false);
 1323  
                         }                              
 1324  0
                     }
 1325  
                     
 1326  
                 }); 
 1327  
 
 1328  0
                 SectionTitle headerTitle = SectionTitle.generateH3Title("Return Proposal to Previous Node");
 1329  0
                 SectionTitle dialogLabel = SectionTitle.generateH4Title("You are returning the " + proposalName + " proposal to a previous node");
 1330  0
                 SectionTitle nnFieldLabel = SectionTitle.generateH4Title("Workflow Node Name");
 1331  0
                 SectionTitle drFieldLabel = SectionTitle.generateH4Title("Decision Rationale");
 1332  0
                 required = new AbbrPanel("Required", "ks-form-module-elements-required", " * ");
 1333  0
                 required.setVisible(true);
 1334  0
                 rationaleEditor.addStyleName("KS-Comment-Create-Editor");
 1335  0
                 dialogPanel.clear();
 1336  0
                 submitSuccessDialog.clearButtons();
 1337  0
                 submitSuccessDialog.setNonCaptionHeader(headerTitle);
 1338  0
                 dialogPanel.add(dialogLabel);
 1339  0
                 dialogPanel.add(nnFieldLabel);
 1340  0
                 dialogPanel.add(nodeNameDropDown);
 1341  0
                 dialogPanel.add(drFieldLabel);
 1342  0
                 dialogPanel.add(required);
 1343  0
                 dialogPanel.add(rationaleEditor);
 1344  0
                 submitSuccessDialog.addButtonGroup(returnButton);
 1345  
                 //dialogPanel.setSize("580px", "400px");
 1346  0
                 dialogPanel.setHeight("380px");
 1347  
                 // submitSuccessDialog.setWidget(dialogPanel);
 1348  0
                 submitSuccessDialog.show();
 1349  0
             }
 1350  
         });
 1351  0
         return wfReturnToPreviousItem;
 1352  
         }
 1353  
 
 1354  
     private void addRationale(KSRichEditor rationaleEditor, String rationaleType) {
 1355  0
         CommentInfo newDecisionRationale = new CommentInfo();
 1356  0
         RichTextInfo text = new RichTextInfo();
 1357  0
         text.setFormatted(rationaleEditor.getHTML());
 1358  0
         text.setPlain(rationaleEditor.getText());
 1359  0
         newDecisionRationale.setReferenceTypeKey(PROPOSAL_REF_TYPE_KEY);
 1360  0
         newDecisionRationale.setReferenceId(proposalId);
 1361  0
         newDecisionRationale.setState(DtoState.ACTIVE.toString());
 1362  0
         newDecisionRationale.setCommentText(text);
 1363  0
         newDecisionRationale.setType(rationaleType);
 1364  
 
 1365  
         try {
 1366  0
             commentServiceAsync.addComment(proposalId, PROPOSAL_REF_TYPE_KEY, newDecisionRationale, new KSAsyncCallback<CommentInfo>() {
 1367  
 
 1368  
                 @Override
 1369  
                 public void handleFailure(Throwable caught) {
 1370  0
                     GWT.log("Add Comment Failed", caught);
 1371  0
                 }
 1372  
 
 1373  
                 @Override
 1374  
                 public void onSuccess(CommentInfo result) {
 1375  0
                     System.out.println("Rationale Added successfully");
 1376  0
                 }
 1377  
             });
 1378  0
         } catch (Exception e) {
 1379  0
             GWT.log("Add Comment Failed", e);
 1380  0
         }
 1381  0
     }
 1382  
 
 1383  
     private KSMenuItemData getStartItem() {
 1384  
         KSMenuItemData wfStartWorkflowItem;
 1385  0
             wfStartWorkflowItem = new KSMenuItemData("Submit Proposal", new ClickHandler(){
 1386  
                     public void onClick(ClickEvent event) {
 1387  
                 //Make sure the entire data model is valid before submit
 1388  0
                                 dataModel.validateNextState(new Callback<List<ValidationResultInfo>>() {
 1389  
                     @Override
 1390  
                     public void exec(List<ValidationResultInfo> result) {
 1391  
                             
 1392  0
                         boolean isValid = parentController.isValid(result, false);
 1393  0
                             if(isValid){
 1394  0
                                             dialog.show();
 1395  
                             }
 1396  
                             else{
 1397  0
                                     Window.alert("Unable to submit to workflow.  Please check sections for missing fields.");
 1398  
                             }                            
 1399  0
                     }
 1400  
                 });
 1401  0
                     }
 1402  
 
 1403  
             });
 1404  0
                 return wfStartWorkflowItem;
 1405  
         }
 1406  
 
 1407  
     private KSMenuItemData getCancelWorkflowItem() {
 1408  
         KSMenuItemData wfCancelWorkflowItem;
 1409  0
         wfCancelWorkflowItem = new KSMenuItemData("Cancel Proposal", new ClickHandler() {
 1410  
             public void onClick(ClickEvent event) {        
 1411  0
                     ConfirmationDialog confirmationCancelProposal = getConfirmationCancelProposalDialog(null);
 1412  0
                     confirmationCancelProposal.show();
 1413  0
             }
 1414  
         });
 1415  0
         return wfCancelWorkflowItem;
 1416  
     }
 1417  
 
 1418  
     protected ConfirmationDialog getConfirmationCancelProposalDialog (final Callback<Boolean> onSuccessCallback){
 1419  0
             final ConfirmationDialog confirmationCancelProposal = new ConfirmationDialog("Cancel Proposal","This action is not reversible and all data will be lost. Do you wish to cancel this proposal?");
 1420  
         
 1421  0
             confirmationCancelProposal.getConfirmButton().setText("Yes, cancel proposal");
 1422  0
             confirmationCancelProposal.getCancelButton().setStyleName(ButtonStyle.PRIMARY_SMALL.getStyle());
 1423  0
         confirmationCancelProposal.getCancelButton().setText("No, return to proposal");
 1424  
            
 1425  0
             confirmationCancelProposal.getConfirmButton().addClickHandler(new ClickHandler(){
 1426  
                     @Override
 1427  
                     public void onClick(ClickEvent event) {
 1428  0
                             workflowRpcServiceAsync.cancelDocumentWithId(workflowId, new KSAsyncCallback<Boolean>() {
 1429  
                                     @Override
 1430  
                     public void handleFailure(Throwable caught) {
 1431  0
                                             confirmationCancelProposal.hide();
 1432  0
                                             Window.alert("Error Cancelling Proposal");
 1433  0
                                     }
 1434  
                                     public void onSuccess(Boolean result) {
 1435  0
                                             confirmationCancelProposal.hide();
 1436  0
                                             if (result) {
 1437  0
                                                     updateWorkflow(dataModel);
 1438  0
                                                     if (submitCallback != null) {
 1439  0
                                                             submitCallback.exec(true);
 1440  
                                                     }
 1441  0
                                                     if (onSuccessCallback != null){
 1442  0
                                                             onSuccessCallback.exec(true);
 1443  
                                                     }
 1444  
                                                     // Notify the user that the document was canceled
 1445  0
                                                     KSNotifier.add(new KSNotification("Proposal will be Cancelled", false));
 1446  
                                             } else {
 1447  0
                                                     Window.alert("Error Cancelling Proposal");
 1448  
                                             }
 1449  0
                                     }
 1450  
                             });
 1451  
                     
 1452  0
                     }
 1453  
 
 1454  
         });  
 1455  
             
 1456  0
             return confirmationCancelProposal;
 1457  
     }
 1458  
     
 1459  
     private void setWorkflowStatus(String statusCd){
 1460  0
                 String statusTranslation = "";
 1461  0
                 if (WorkflowConstants.ROUTE_HEADER_SAVED_CD.equals(statusCd)){
 1462  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_SAVED_LABEL_KEY);
 1463  0
                 } else  if (WorkflowConstants.ROUTE_HEADER_INITIATED_CD.equals(statusCd)){
 1464  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_INITIATED_LABEL_KEY);
 1465  0
                 } else if (WorkflowConstants.ROUTE_HEADER_ENROUTE_CD.equals(statusCd)){
 1466  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_ENROUTE_LABEL_KEY);
 1467  0
                 } else if (WorkflowConstants.ROUTE_HEADER_APPROVED_CD.equals(statusCd)){
 1468  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_APPROVED_LABEL_KEY);
 1469  0
                 } else if (WorkflowConstants.ROUTE_HEADER_CANCEL_CD.equals(statusCd)){
 1470  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_CANCEL_LABEL_KEY);
 1471  0
                 } else if (WorkflowConstants.ROUTE_HEADER_EXCEPTION_CD.equals(statusCd)){
 1472  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_EXCEPTION_LABEL_KEY);
 1473  0
                 } else if (WorkflowConstants.ROUTE_HEADER_DISAPPROVED_CD.equals(statusCd)){
 1474  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_DISAPPROVED_LABEL_KEY);
 1475  0
                 } else if (WorkflowConstants.ROUTE_HEADER_FINAL_CD.equals(statusCd)){
 1476  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_APPROVED_LABEL_KEY);//getLabel(WorkflowConstants.ROUTE_HEADER_FINAL_LABEL_KEY);
 1477  0
                 } else if (WorkflowConstants.ROUTE_HEADER_DISAPPROVE_CANCEL_CD.equals(statusCd)){
 1478  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_DISAPPROVE_CANCEL_LABEL_KEY);
 1479  0
                 } else if (WorkflowConstants.ROUTE_HEADER_PROCESSED_CD.equals(statusCd)){
 1480  0
                         statusTranslation = getLabel(WorkflowConstants.ROUTE_HEADER_APPROVED_LABEL_KEY);//getLabel(WorkflowConstants.ROUTE_HEADER_PROCESSED_LABEL_KEY);
 1481  
                 } else {
 1482  0
                         statusTranslation = statusCd;
 1483  
                 }
 1484  
                 
 1485  0
                 workflowStatusLabel.setText("Status: " + statusTranslation);        
 1486  0
         }
 1487  
         
 1488  
     private void setProposalStatus(String statusCode) {
 1489  0
         String statusLabel = Application.getApplicationContext()
 1490  
                 .getUILabel("common", null, null, "proposalStatusLabel");
 1491  0
         String status = Application.getApplicationContext().getUILabel("common", null, null, statusCode);
 1492  
 
 1493  0
         proposalStatusLabel.setText(statusLabel + ": " + status);
 1494  0
     }
 1495  
 
 1496  
     /**
 1497  
      * Use to set the modelName to use when this widget requests the data model.
 1498  
      * 
 1499  
      * @param modelName
 1500  
      */
 1501  
         public void setModelName(String modelName) {
 1502  0
                 this.modelName = modelName;
 1503  0
         }
 1504  
         
 1505  
         /**
 1506  
          * Use to set the data model path to retrieve the propsal data to use for this workflow. 
 1507  
          * @param idPath
 1508  
          */
 1509  
         public void setProposalPath(String proposalPath) {
 1510  0
                 this.proposalPath = proposalPath;
 1511  0
         }
 1512  
                 
 1513  
         public void setWorkflowRpcService(WorkflowRpcServiceAsync workflowRpcServiceAsync){
 1514  0
                 this.workflowRpcServiceAsync = workflowRpcServiceAsync;
 1515  0
         }
 1516  
 
 1517  
     //TODO: currently causing a lot of duplicate calls and has to be used carefully. Commented out for now.
 1518  
         public void refresh(){
 1519  0
             updateApproveFields();
 1520  0
                 updateWorkflow(dataModel);
 1521  0
         }
 1522  
         
 1523  
     private String getLabel(String labelKey) {
 1524  0
         return Application.getApplicationContext().getUILabel("common", null, null, labelKey);
 1525  
     }
 1526  
     
 1527  
     public void getDataIdFromWorkflowId(String workflowId, AsyncCallback<String> callback){
 1528  0
             workflowRpcServiceAsync.getDataIdFromWorkflowId(workflowId, callback);
 1529  0
     }
 1530  
 
 1531  
         public void addSubmitCallback(Callback<Boolean> callback) {
 1532  0
                 this.submitCallback = callback;
 1533  
                 
 1534  0
         }
 1535  
 
 1536  
         public List<KSMenuItemData> getAdditionalItems() {
 1537  0
                 return additionalItems;
 1538  
         }
 1539  
 
 1540  
         public void addIgnoreDialogField(String string) {
 1541  0
                 ignoredApproveDialogFields.add(string);
 1542  0
         }
 1543  
         
 1544  
         public VerticalSectionView getApproveDialogue() {
 1545  0
             return approveDialogView;
 1546  
         }
 1547  
         
 1548  
     public void progressiveEnableFields() {
 1549  0
         if (getApproveDialogue() != null) {
 1550  
             
 1551  0
             FieldDescriptor prevEndTerm = approveDialogView.getField("proposal/prevEndTerm");
 1552  
 
 1553  0
             if (prevEndTerm != null) {
 1554  0
                 approveDialogView.getWidget(0).setVisible(true);
 1555  0
                 approveDialogView.getField("proposal/prevEndTerm").getMetadata().getConstraints().get(0).setMinOccurs(1);
 1556  0
                 approveDialogView.getField("proposal/prevEndTerm").getFieldElement().setRequiredString("requiredMarker", "ks-form-module-elements-required");
 1557  0
                 approveDialogView.getField("startTerm").getFieldWidget().setVisible(true);
 1558  
             } else {
 1559  0
                 approveDialogView.getWidget(0).setVisible(false);
 1560  0
                 approveDialogView.getField("startTerm").getFieldWidget().setVisible(false);
 1561  
             }
 1562  
         }
 1563  0
     }
 1564  
     
 1565  
 }