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