Coverage Report - org.kuali.student.lum.program.client.major.proposal.MajorProposalController
 
Classes in this File Line Coverage Branch Coverage Complexity
MajorProposalController
0%
0/249
0%
0/96
1.989
MajorProposalController$1
0%
0/3
N/A
1.989
MajorProposalController$10
0%
0/3
N/A
1.989
MajorProposalController$10$1
0%
0/3
N/A
1.989
MajorProposalController$11
0%
0/5
0%
0/4
1.989
MajorProposalController$12
0%
0/5
0%
0/4
1.989
MajorProposalController$13
0%
0/14
0%
0/2
1.989
MajorProposalController$14
0%
0/5
N/A
1.989
MajorProposalController$14$1
0%
0/8
N/A
1.989
MajorProposalController$14$1$1
0%
0/4
0%
0/2
1.989
MajorProposalController$14$1$1$1
0%
0/4
0%
0/2
1.989
MajorProposalController$15
0%
0/5
N/A
1.989
MajorProposalController$15$1
0%
0/8
N/A
1.989
MajorProposalController$15$1$1
0%
0/4
0%
0/2
1.989
MajorProposalController$15$1$1$1
0%
0/4
0%
0/2
1.989
MajorProposalController$16
0%
0/11
N/A
1.989
MajorProposalController$17
0%
0/9
N/A
1.989
MajorProposalController$18
0%
0/6
N/A
1.989
MajorProposalController$18$1
0%
0/7
0%
0/2
1.989
MajorProposalController$19
0%
0/44
0%
0/10
1.989
MajorProposalController$2
0%
0/3
N/A
1.989
MajorProposalController$20
0%
0/6
0%
0/2
1.989
MajorProposalController$21
0%
0/6
0%
0/4
1.989
MajorProposalController$21$1
0%
0/5
0%
0/4
1.989
MajorProposalController$21$1$1
0%
0/6
N/A
1.989
MajorProposalController$22
0%
0/5
N/A
1.989
MajorProposalController$23
0%
0/4
N/A
1.989
MajorProposalController$24
0%
0/10
0%
0/2
1.989
MajorProposalController$3
0%
0/6
0%
0/2
1.989
MajorProposalController$4
0%
0/3
N/A
1.989
MajorProposalController$4$1
0%
0/3
N/A
1.989
MajorProposalController$4$1$1
0%
0/11
0%
0/6
1.989
MajorProposalController$4$1$1$1
0%
0/5
0%
0/2
1.989
MajorProposalController$4$1$1$1$1
0%
0/5
0%
0/2
1.989
MajorProposalController$5
0%
0/27
0%
0/10
1.989
MajorProposalController$6
0%
0/12
0%
0/2
1.989
MajorProposalController$7
0%
0/13
0%
0/4
1.989
MajorProposalController$7$1
0%
0/3
N/A
1.989
MajorProposalController$7$1$1
0%
0/7
N/A
1.989
MajorProposalController$7$1$1$1
0%
0/2
N/A
1.989
MajorProposalController$8
0%
0/3
N/A
1.989
MajorProposalController$9
0%
0/4
0%
0/2
1.989
 
 1  
 package org.kuali.student.lum.program.client.major.proposal;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.HashMap;
 5  
 import java.util.Iterator;
 6  
 import java.util.List;
 7  
 import java.util.Map;
 8  
 import java.util.Set;
 9  
 import java.util.TreeSet;
 10  
 
 11  
 import org.kuali.student.common.assembly.data.Data;
 12  
 import org.kuali.student.common.assembly.data.Data.Property;
 13  
 import org.kuali.student.common.assembly.data.Metadata;
 14  
 import org.kuali.student.common.assembly.data.QueryPath;
 15  
 import org.kuali.student.common.dto.DtoConstants;
 16  
 import org.kuali.student.common.rice.StudentIdentityConstants;
 17  
 import org.kuali.student.common.rice.authorization.PermissionType;
 18  
 import org.kuali.student.common.ui.client.application.Application;
 19  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 20  
 import org.kuali.student.common.ui.client.application.ViewContext;
 21  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.CollapsableSection;
 22  
 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
 23  
 import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView;
 24  
 import org.kuali.student.common.ui.client.event.SaveActionEvent;
 25  
 import org.kuali.student.common.ui.client.event.SaveActionHandler;
 26  
 import org.kuali.student.common.ui.client.mvc.ApplicationEvent;
 27  
 import org.kuali.student.common.ui.client.mvc.Callback;
 28  
 import org.kuali.student.common.ui.client.mvc.DataModel;
 29  
 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
 30  
 import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
 31  
 import org.kuali.student.common.ui.client.mvc.ModelProvider;
 32  
 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
 33  
 import org.kuali.student.common.ui.client.mvc.View;
 34  
 import org.kuali.student.common.ui.client.mvc.dto.ReferenceModel;
 35  
 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
 36  
 import org.kuali.student.common.ui.client.security.AuthorizationCallback;
 37  
 import org.kuali.student.common.ui.client.security.RequiresAuthorization;
 38  
 import org.kuali.student.common.ui.client.service.DataSaveResult;
 39  
 import org.kuali.student.common.ui.client.util.ExportElement;
 40  
 import org.kuali.student.common.ui.client.util.ExportUtils;
 41  
 import org.kuali.student.common.ui.client.validator.ValidatorClientUtils;
 42  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 43  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
 44  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
 45  
 import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
 46  
 import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableSection;
 47  
 import org.kuali.student.common.ui.shared.IdAttributes;
 48  
 import org.kuali.student.common.ui.shared.IdAttributes.IdType;
 49  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 50  
 import org.kuali.student.core.proposal.dto.ProposalInfo;
 51  
 import org.kuali.student.core.proposal.ui.client.service.ProposalRpcService;
 52  
 import org.kuali.student.core.proposal.ui.client.service.ProposalRpcServiceAsync;
 53  
 import org.kuali.student.core.workflow.ui.client.widgets.WorkflowEnhancedNavController;
 54  
 import org.kuali.student.core.workflow.ui.client.widgets.WorkflowUtilities;
 55  
 import org.kuali.student.lum.common.client.configuration.LUMViews;
 56  
 import org.kuali.student.lum.common.client.helpers.RecentlyViewedHelper;
 57  
 import org.kuali.student.lum.common.client.widgets.AppLocations;
 58  
 import org.kuali.student.lum.lu.LUConstants;
 59  
 import org.kuali.student.lum.program.client.ProgramConstants;
 60  
 import org.kuali.student.lum.program.client.ProgramMsgConstants;
 61  
 import org.kuali.student.lum.program.client.ProgramRegistry;
 62  
 import org.kuali.student.lum.program.client.ProgramSections;
 63  
 import org.kuali.student.lum.program.client.ProgramStatus;
 64  
 import org.kuali.student.lum.program.client.ProgramUtils;
 65  
 import org.kuali.student.lum.program.client.events.AddSpecializationEvent;
 66  
 import org.kuali.student.lum.program.client.events.AfterSaveEvent;
 67  
 import org.kuali.student.lum.program.client.events.ChangeViewEvent;
 68  
 import org.kuali.student.lum.program.client.events.MetadataLoadedEvent;
 69  
 import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
 70  
 import org.kuali.student.lum.program.client.events.SpecializationCreatedEvent;
 71  
 import org.kuali.student.lum.program.client.events.SpecializationSaveEvent;
 72  
 import org.kuali.student.lum.program.client.events.SpecializationUpdateEvent;
 73  
 import org.kuali.student.lum.program.client.events.StateChangeEvent;
 74  
 import org.kuali.student.lum.program.client.events.StoreRequirementIDsEvent;
 75  
 import org.kuali.student.lum.program.client.events.UpdateEvent;
 76  
 import org.kuali.student.lum.program.client.major.MajorController;
 77  
 import org.kuali.student.lum.program.client.requirements.ProgramRequirementsDataModel;
 78  
 import org.kuali.student.lum.program.client.rpc.AbstractCallback;
 79  
 import org.kuali.student.lum.program.client.rpc.MajorDisciplineProposalRpcService;
 80  
 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcService;
 81  
 import org.kuali.student.lum.program.client.rpc.MajorDisciplineRpcServiceAsync;
 82  
 import org.kuali.student.lum.program.client.widgets.ProgramSideBar;
 83  
 
 84  
 import com.google.gwt.core.client.GWT;
 85  
 import com.google.gwt.event.dom.client.ClickEvent;
 86  
 import com.google.gwt.event.dom.client.ClickHandler;
 87  
 import com.google.gwt.event.shared.HandlerManager;
 88  
 import com.google.gwt.user.client.Window;
 89  
 
 90  
 /**
 91  
  * @author Igor
 92  
  */
 93  0
 public class MajorProposalController extends MajorController implements WorkflowEnhancedNavController, RequiresAuthorization{
 94  
 
 95  
         private final KSButton saveButton;
 96  
     private final KSButton cancelButton;
 97  0
     private final Set<String> existingVariationIds = new TreeSet<String>();
 98  0
     protected String proposalPath = "";
 99  
     protected WorkflowUtilities workflowUtil; 
 100  0
     private final ProposalRpcServiceAsync proposalServiceAsync = GWT.create(ProposalRpcService.class);
 101  
 
 102  0
         protected final DataModel comparisonModel = new DataModel("Original Program");
 103  0
         private String comparisonModelId = "ComparisonModel";
 104  
 
 105  0
         protected final DataModel reqModel = new DataModel("");
 106  0
         private String reqModelId = "reqModel";
 107  
 
 108  
     private ProgramRequirementsDataModel reqDataModel;
 109  
     private ProgramRequirementsDataModel reqDataModelComp;
 110  
 
 111  
     protected MajorDisciplineRpcServiceAsync majorDisciplineService;
 112  
 
 113  
     /**
 114  
      * Constructor.
 115  
      *
 116  
      * @param programModel
 117  
      */
 118  
     public MajorProposalController(DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
 119  0
         super(programModel, viewContext, eventBus); 
 120  0
         majorDisciplineService = createMajorDisciplineService();
 121  0
         programModel.setModelName("Proposal");
 122  0
         initializeComparisonModel();
 123  0
         configurer = GWT.create(MajorProposalConfigurer.class);
 124  
         
 125  0
         saveButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_SAVE));
 126  0
         cancelButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_CANCEL), KSButtonAbstract.ButtonStyle.ANCHOR_LARGE_CENTERED);
 127  
         
 128  0
         proposalPath = configurer.getProposalPath();
 129  0
         workflowUtil = new WorkflowUtilities(MajorProposalController.this, proposalPath, "Proposal Actions",
 130  
                                    ProgramSections.WF_APPROVE_DIALOG,"Required Fields", ProgramConstants.PROGRAM_MODEL_ID);
 131  
 
 132  0
         sideBar.setState(ProgramSideBar.State.EDIT);
 133  0
         initHandlers();
 134  
                 
 135  0
         reqDataModel = new ProgramRequirementsDataModel(eventBus);
 136  0
         reqDataModelComp = new ProgramRequirementsDataModel(eventBus);
 137  0
     }
 138  
       
 139  
     /**
 140  
      *  Overriding this method from the proposal controller and using the newly 
 141  
      *  defined reference type (referenceType.clu.proposal.program).  This will
 142  
      *  ensure comments stay with the proposal as it moves through the workflow.
 143  
      *  
 144  
      *  See KSLAB-2070
 145  
      */
 146  
     @Override
 147  
     public void requestModel(Class modelType, ModelRequestCallback callback) {
 148  0
         if (modelType == ReferenceModel.class) {
 149  0
             ReferenceModel referenceModel = new ReferenceModel();
 150  
             
 151  
             // Set the reference ID to the proposal ID (as opposed to the program ID)
 152  
             // so that supporting documents and comments will be linked to proposal
 153  
             // as opposed to being linked to the original program.
 154  0
             referenceModel.setReferenceId(ProgramUtils.getProposalId(programModel));
 155  
            
 156  
             // The referenceTypeKey maps to the KSCO_REFERENCE_TYPE table.   
 157  
             // We are using the new value referenceType.clu.proposal.program (the new type added for program proposals)
 158  0
             referenceModel.setReferenceTypeKey(ProgramConstants.PROPOSAL_REFERENCE_TYPE_ID);
 159  
             
 160  
             // This maps to KSLU_LUTYPE table.
 161  
             // Key value it is looking up is kuali.lu.type.MajorDiscipline
 162  
             // We can keep this the same for both programs and proposals
 163  0
             referenceModel.setReferenceType(ProgramConstants.MAJOR_LU_TYPE_ID);
 164  
            
 165  0
             Map<String, String> attributes = new HashMap<String, String>();
 166  0
             attributes.put("name", getStringProperty("name"));
 167  0
             referenceModel.setReferenceAttributes(attributes);
 168  0
             callback.onModelReady(referenceModel);
 169  0
         } else {
 170  0
             super.requestModel(modelType, callback);
 171  
         }
 172  0
     }
 173  
     
 174  
     /**
 175  
      * We need to override the method in MajorDisciplineController
 176  
      * to ensure our custom proposal service is called, which has
 177  
      * the filter needed to pull proposal info out of the model.
 178  
      */
 179  
     @Override
 180  
     protected MajorDisciplineRpcServiceAsync createProgramRemoteService() {
 181  0
         return GWT.create(MajorDisciplineProposalRpcService.class);
 182  
     }
 183  
 
 184  
     /**
 185  
      * Create a ProgramRpcServiceAsync appropriate for this Controller
 186  
      */
 187  
     protected MajorDisciplineRpcServiceAsync createMajorDisciplineService() {
 188  0
         return GWT.create(MajorDisciplineRpcService.class);
 189  
     }
 190  
 
 191  
     @Override
 192  
     protected void configureView() {
 193  0
         super.configureView();
 194  0
         if (!initialized) {
 195  0
             eventBus.fireEvent(new MetadataLoadedEvent(programModel.getDefinition(), this));
 196  0
             List<Enum<?>> excludedViews = new ArrayList<Enum<?>>();
 197  0
             excludedViews.add(ProgramSections.PROGRAM_REQUIREMENTS_EDIT);
 198  0
             excludedViews.add(ProgramSections.SUPPORTING_DOCUMENTS_EDIT);
 199  0
             excludedViews.add(ProgramSections.SUMMARY);
 200  0
             addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), saveButton, excludedViews);
 201  0
             addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), cancelButton, excludedViews);
 202  0
             initialized = true;
 203  
         }
 204  0
     }
 205  
 
 206  
     /**
 207  
      * 
 208  
      * This overridden method is called by the framework to pass request parameters (basically).
 209  
      * <p>
 210  
      * See https://wiki.kuali.org/display/STUDENTDOC/6.4+History%2C+Breadcrumbs+and+ViewContext
 211  
      * <p>
 212  
      * 
 213  
      * @see org.kuali.student.lum.program.client.ProgramController#setViewContext(org.kuali.student.common.ui.client.application.ViewContext)
 214  
      */
 215  
     @Override
 216  
     public void setViewContext(ViewContext viewContext) {
 217  0
         super.setViewContext(viewContext);
 218  0
         if(viewContext.getId() != null && !viewContext.getId().isEmpty()){
 219  0
             if(viewContext.getIdType() != IdType.COPY_OF_OBJECT_ID && viewContext.getIdType() != IdType.COPY_OF_KS_KEW_OBJECT_ID){
 220  
                 
 221  0
                 viewContext.setPermissionType(PermissionType.OPEN);
 222  
             } else{
 223  
                 // Since we are making a copy and we are in the proposal controller we know
 224  
                 // we are submitting a new proposal.  We need to reset the model so that
 225  
                 // work flow utilities reloads it.  This method is called multiple times 
 226  
                 // by the history stack. 
 227  0
                 resetModel();
 228  
                 //they are trying to make a modification
 229  0
                 viewContext.setPermissionType(PermissionType.INITIATE);
 230  
             }
 231  
         }
 232  
         else{
 233  0
             viewContext.setPermissionType(PermissionType.INITIATE);
 234  
         }
 235  0
     }
 236  
 
 237  
     /**
 238  
      * Used by configurer when adding widget to the screen.  Allows
 239  
      * us to get the workflow utilities we initialize in the 
 240  
      * controller. 
 241  
      * @return
 242  
      */
 243  
     public WorkflowUtilities getWfUtilities(){
 244  0
         return workflowUtil;
 245  
     }
 246  
     
 247  
     private void initHandlers() {
 248  0
         saveButton.addClickHandler(new ClickHandler() {
 249  
 
 250  
             @Override
 251  
             public void onClick(ClickEvent event) {
 252  0
                 doSave();
 253  0
             }
 254  
         });
 255  0
         cancelButton.addClickHandler(new ClickHandler() {
 256  
 
 257  
             @Override
 258  
             public void onClick(ClickEvent event) {
 259  0
                 doCancel();
 260  0
             }
 261  
         });
 262  0
         eventBus.addHandler(UpdateEvent.TYPE, new UpdateEvent.Handler() {
 263  
             @Override
 264  
             public void onEvent(UpdateEvent event) {
 265  0
                 Enum<?> view = event.getCurrentView();
 266  0
                 if (view != null) {
 267  0
                     setCurrentViewEnum(view);
 268  
                 }
 269  0
                 doSave(event.getOkCallback());
 270  
 
 271  0
             }
 272  
         });
 273  0
         eventBus.addHandler(StateChangeEvent.TYPE, new StateChangeEvent.Handler() {
 274  
             @Override
 275  
             public void onEvent(final StateChangeEvent event) {
 276  
                     //FIXME: The proper way of doing this would be a single server side call to validate next state
 277  
                     //which would retrieve warnings & required for next state, instead of re-validating warnings for
 278  
                     //current state server side and validating required for next state client side.
 279  0
                     programRemoteService.validate(programModel.getRoot(), new KSAsyncCallback<List<ValidationResultInfo>>(){
 280  
                                         @Override
 281  
                                         public void onSuccess(final List<ValidationResultInfo> currentStateResults) {
 282  0
                                 programModel.validateNextState(new Callback<List<ValidationResultInfo>>() {
 283  
                                     @Override
 284  
                                     public void exec(List<ValidationResultInfo> nextStateResults) {
 285  
                                             //Update validation warnings and process for all screens
 286  0
                                             Application.getApplicationContext().clearValidationWarnings();
 287  0
                                             Application.getApplicationContext().addValidationWarnings(currentStateResults);
 288  0
                                             isValid(Application.getApplicationContext().getValidationWarnings(), false);
 289  
                                         
 290  0
                                             boolean isSectionValid = isValid(nextStateResults, true) 
 291  
                                                 && Application.getApplicationContext().getValidationWarnings().isEmpty();
 292  0
                                         if (isSectionValid) {
 293  0
                                             Callback<Boolean> callback = new Callback<Boolean>() {
 294  
                                                 @Override
 295  
                                                 public void exec(Boolean result) {
 296  0
                                                     if (result) {
 297  0
                                                         reloadMetadata = true;
 298  0
                                                         loadMetadata(new Callback<Boolean>() {
 299  
                                                             @Override
 300  
                                                             public void exec(Boolean result) {
 301  0
                                                                 if (result) {
 302  0
                                                                     ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
 303  0
                                                                     HistoryManager.navigate(AppLocations.Locations.VIEW_PROGRAM.getLocation(), context);
 304  
                                                                 }
 305  0
                                                             }
 306  
                                                         });
 307  
                                                     }
 308  0
                                                 }
 309  
                                             };
 310  0
                                             updateState(event.getProgramStatus().getValue(), callback);
 311  0
                                         } else {
 312  0
                                             KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
 313  
                                         }
 314  0
                                     }
 315  
                                 });                                                
 316  0
                                         }                            
 317  
                     });                
 318  0
             }
 319  
         });
 320  
 
 321  0
         eventBus.addHandler(SpecializationSaveEvent.TYPE, new SpecializationSaveEvent.Handler() {
 322  
             @Override
 323  
             public void onEvent(SpecializationSaveEvent event) {
 324  
 
 325  0
                 Data currentVariations = getDataProperty(ProgramConstants.VARIATIONS);
 326  
 
 327  0
                 existingVariationIds.clear();
 328  
 
 329  0
                 for (Data.Property prop : currentVariations) {
 330  0
                     String existingId = (String) ((Data) prop.getValue()).get(ProgramConstants.ID);
 331  0
                     existingVariationIds.add(existingId);
 332  0
                 }
 333  0
                 String updatedId = event.getData().get(ProgramConstants.ID);
 334  0
                 Integer updatedKey = null;
 335  
 
 336  
                 //FIXME: This is ugly but gets us past a  blocker issue. 
 337  
                 // Theres something wrong with the way the models are
 338  
                 // handled in the major and variation controllers  so they get out of sync.
 339  
                 // This is a temporary workaround
 340  0
                 if (updatedId != null) { // this is an update of an existing variation
 341  0
                     for (Data.Property prop : currentVariations) {
 342  0
                         String id = (String) ((Data) prop.getValue()).get(ProgramConstants.ID);
 343  0
                         if (updatedId.equals(id)) {
 344  0
                             updatedKey = prop.getKey();
 345  0
                             Data currentMetaInfo = ((Data) prop.getValue()).get("metaInfo");
 346  0
                             String latestVersionInd = currentMetaInfo.get("versionInd");
 347  0
                             Data newMetaInfo = event.getData().get("metaInfo");
 348  0
                             if (newMetaInfo == null) {
 349  0
                                 newMetaInfo = new Data();
 350  0
                                 event.getData().set("metaInfo", newMetaInfo);
 351  
                             }
 352  0
                             newMetaInfo.set("versionInd", latestVersionInd);
 353  0
                             break;
 354  
                         }
 355  0
                     }
 356  
 
 357  0
                     currentVariations.set(updatedKey, event.getData());
 358  
                 } else {
 359  0
                     currentVariations.add(event.getData());
 360  
 
 361  
                 }
 362  0
                 doSave();
 363  0
             }
 364  
         });
 365  0
         eventBus.addHandler(AddSpecializationEvent.TYPE, new AddSpecializationEvent.Handler() {
 366  
             @Override
 367  
             public void onEvent(AddSpecializationEvent event) {
 368  0
                 String id = getStringProperty(ProgramConstants.ID);
 369  0
                 ProgramRegistry.setRow((getDataProperty(ProgramConstants.VARIATIONS)).size());
 370  0
                 Data variationData = ProgramUtils.createNewSpecializationBasedOnMajor(programModel);
 371  0
                 ProgramRegistry.setData(variationData);
 372  0
                 ViewContext viewContext = new ViewContext();
 373  0
                 viewContext.setId(id);
 374  0
                 viewContext.setIdType(IdAttributes.IdType.OBJECT_ID);
 375  0
                 if(programModel.get("proposal/id") != null){
 376  
                     // It is a proposal
 377  0
                     variationData.set("isProposal", true);
 378  
                 }
 379  0
                 HistoryManager.navigate(AppLocations.Locations.EDIT_VARIATION.getLocation(), viewContext);
 380  
 
 381  0
             }
 382  
         });
 383  
 
 384  0
         eventBus.addHandler(StoreRequirementIDsEvent.TYPE, new StoreRequirementIDsEvent.Handler() {
 385  
             @Override
 386  
             public void onEvent(StoreRequirementIDsEvent event) {
 387  0
                 List<String> ids = event.getProgramRequirementIds();
 388  
 
 389  0
                 programModel.set(QueryPath.parse(ProgramConstants.PROGRAM_REQUIREMENTS), new Data());
 390  0
                 Data programRequirements = programModel.get(ProgramConstants.PROGRAM_REQUIREMENTS);
 391  
 
 392  0
                 if (programRequirements == null) {
 393  0
                     Window.alert("Cannot find program requirements in data model.");
 394  0
                     GWT.log("Cannot find program requirements in data model", null);
 395  0
                     return;
 396  
                 }
 397  
 
 398  0
                 for (String id : ids) {
 399  0
                     programRequirements.add(id);
 400  
                 }
 401  
                 
 402  0
                     Callback<Boolean> reqCallback = new Callback<Boolean>() {
 403  
                             @Override
 404  
                             public void exec(Boolean result) {
 405  0
                                     majorDisciplineService.getData(getViewContext().getId(), new AbstractCallback<Data>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
 406  
                             @Override
 407  
                             public void onSuccess(Data result) {
 408  0
                                 super.onSuccess(result);
 409  0
                                 reqModel.setRoot(result);
 410  0
                                 reqDataModel.retrieveProgramRequirements(MajorProposalController.this, reqModelId, new Callback<Boolean>() {
 411  
                                     @Override
 412  0
                                     public void exec(Boolean result) {}
 413  
                                 });                    
 414  0
                             }
 415  
                             
 416  
                             @Override
 417  
                             public void onFailure(Throwable caught) {
 418  0
                                 super.onFailure(caught);
 419  0
                             }
 420  
                         });
 421  0
                             }
 422  
                     };
 423  
 
 424  0
                 doSave(reqCallback);
 425  0
             }
 426  
         });
 427  0
         eventBus.addHandler(ChangeViewEvent.TYPE, new ChangeViewEvent.Handler() {
 428  
             @Override
 429  
             public void onEvent(ChangeViewEvent event) {
 430  0
                 showView(event.getViewToken());
 431  0
             }
 432  
         });
 433  0
         eventBus.addHandler(ModelLoadedEvent.TYPE, new ModelLoadedEvent.Handler(){
 434  
                         @Override
 435  
                         public void onEvent(ModelLoadedEvent event) {
 436  0
                                 if (workflowUtil != null){
 437  0
                                         workflowUtil.requestAndSetupModel(NO_OP_CALLBACK);
 438  
                                         
 439  
                                 }
 440  0
                         }                
 441  
         });
 442  
         
 443  0
         addApplicationEventHandler(SaveActionEvent.TYPE, new SaveActionHandler(){
 444  
                         @Override
 445  
                         public void doSave(final SaveActionEvent saveAction) {
 446  0
                                 MajorProposalController.this.doSave(new Callback<Boolean>(){
 447  
                                         @Override
 448  
                                         public void exec(Boolean result) {
 449  0
                                                 saveAction.doActionComplete();
 450  0
                                         }
 451  
                                 });
 452  0
                         }
 453  
         });
 454  0
    }
 455  
 
 456  
     /* (non-Javadoc)
 457  
      * @see org.kuali.student.common.ui.client.mvc.Controller#fireApplicationEvent(org.kuali.student.common.ui.client.mvc.ApplicationEvent)
 458  
      */
 459  
     @Override
 460  
         public void fireApplicationEvent(ApplicationEvent event) {
 461  
             //Fire this event from the event bus
 462  0
                 if(event instanceof SaveActionEvent){
 463  0
                         eventBus.fireEvent(event);
 464  
                 }
 465  0
                 super.fireApplicationEvent(event);
 466  0
         }
 467  
 
 468  
     
 469  
     /**
 470  
      * Initialized comparison model of the controller.
 471  
      */
 472  
     private void initializeComparisonModel() {
 473  0
         super.registerModel(comparisonModelId, new ModelProvider<DataModel>() {
 474  
             @Override
 475  
             public void requestModel(final ModelRequestCallback<DataModel> callback) {
 476  0
                     if(comparisonModel.getRoot() != null && comparisonModel.getRoot().size() != 0){
 477  0
                             callback.onModelReady(comparisonModel);                            
 478  
                     }
 479  
                     else{
 480  0
                             callback.onModelReady(null);
 481  
                     }                
 482  0
              }
 483  
         });
 484  
                 
 485  0
         super.registerModel(reqModelId, new ModelProvider<DataModel>() {
 486  
             @Override
 487  
             public void requestModel(final ModelRequestCallback<DataModel> callback) {
 488  0
                     if(reqModel.getRoot() != null && reqModel.getRoot().size() != 0){
 489  0
                             callback.onModelReady(reqModel);                            
 490  
                     }
 491  
                     else{
 492  0
                             callback.onModelReady(null);
 493  
                     }                
 494  0
              }
 495  
         });
 496  0
     }
 497  
 
 498  
     @Override
 499  
     protected void loadMetadata(final Callback<Boolean> onReadyCallback) {
 500  0
         Map<String, String> idAttributes = new HashMap<String, String>();
 501  0
         ViewContext viewContext = getViewContext();
 502  0
         IdType idType = viewContext.getIdType();
 503  0
         String viewContextId = null;
 504  0
         if (idType != null) {
 505  0
             idAttributes.put(IdAttributes.ID_TYPE, idType.toString());
 506  0
             viewContextId = viewContext.getId();
 507  0
             if (idType == IdType.COPY_OF_OBJECT_ID) {
 508  0
                 viewContextId = null;
 509  
             }
 510  
         }
 511  0
         idAttributes.put(StudentIdentityConstants.DOCUMENT_TYPE_NAME, LUConstants.PROPOSAL_TYPE_MAJOR_DISCIPLINE_MODIFY);       
 512  0
         if (programModel.getRoot() != null) {
 513  0
             ProgramStatus programStatus = ProgramStatus.of(programModel);
 514  0
             idAttributes.put(DtoConstants.DTO_STATE, programStatus.getValue());
 515  0
             String workflowNode = programModel.get("proposal/workflowNode");
 516  0
             if(workflowNode!=null){
 517  0
                     idAttributes.put(DtoConstants.DTO_WORKFLOW_NODE, workflowNode);
 518  
             }
 519  
         }
 520  0
         programRemoteService.getMetadata(viewContextId, idAttributes, new AbstractCallback<Metadata>() {
 521  
 
 522  
             @Override
 523  
             public void onSuccess(Metadata result) {
 524  0
                 super.onSuccess(result);
 525  0
                 DataModelDefinition def = new DataModelDefinition(result);
 526  0
                 programModel.setDefinition(def);
 527  0
                 comparisonModel.setDefinition(def);
 528  0
                 lastLoadedStatus = ProgramStatus.of(programModel);
 529  0
                 afterMetadataLoaded(onReadyCallback);
 530  0
                 if (result.isCanEdit()){
 531  0
                     sideBar.setState(ProgramSideBar.State.EDIT);
 532  
                 }else {
 533  0
                         sideBar.setState(ProgramSideBar.State.VIEW);
 534  
                 }
 535  0
             }
 536  
 
 537  
             @Override
 538  
             public void onFailure(Throwable caught) {
 539  0
                 super.onFailure(caught);
 540  0
                 onReadyCallback.exec(false);
 541  0
             }
 542  
         });
 543  0
     }
 544  
 
 545  
     @Override
 546  
     protected void loadModel(final ModelRequestCallback<DataModel> callback) {            
 547  0
             ViewContext viewContext = getViewContext();
 548  0
         if (viewContext.getIdType() == IdType.COPY_OF_OBJECT_ID) 
 549  
         {        
 550  0
                 ModelRequestCallback<DataModel> comparisonModelCallback = new ModelRequestCallback<DataModel>() {
 551  
                             @Override
 552  
                             public void onModelReady(DataModel model) {
 553  0
                                     majorDisciplineService.getData((String)model.get("versionInfo/versionedFromId"), new AbstractCallback<Data>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
 554  
                         @Override
 555  
                         public void onSuccess(Data result) {
 556  0
                             super.onSuccess(result);
 557  0
                             comparisonModel.setRoot(result);
 558  0
                             reqDataModel.retrieveProgramRequirements(MajorProposalController.this, ProgramConstants.PROGRAM_MODEL_ID, new Callback<Boolean>() {
 559  
                                 @Override
 560  
                                 public void exec(Boolean result) {
 561  0
                                     if (result) {
 562  0
                                             reqDataModelComp.retrieveProgramRequirements(MajorProposalController.this, comparisonModelId, new Callback<Boolean>() {
 563  
                                             @Override
 564  
                                             public void exec(Boolean result) {
 565  0
                                                 if (result) {
 566  0
                                                     callback.onModelReady(comparisonModel);
 567  
                                                 }
 568  0
                                             }
 569  
                                         });
 570  
                                     }
 571  0
                                 }
 572  
                             });                    
 573  0
                         }
 574  
                         
 575  
                         @Override
 576  
                         public void onFailure(Throwable caught) {
 577  0
                             super.onFailure(caught);
 578  0
                             callback.onRequestFail(caught);
 579  0
                         }
 580  
                     });
 581  0
                         }
 582  
 
 583  
                             @Override
 584  
                             public void onRequestFail(Throwable cause) {
 585  0
                     GWT.log("Unable to retrieve comparison model", cause);
 586  0
                             }
 587  
                 };        
 588  
                 
 589  0
                            createNewVersionAndLoadModel(comparisonModelCallback, viewContext);                           
 590  0
         }        
 591  
         else
 592  
         {
 593  0
                 ModelRequestCallback<DataModel> comparisonModelCallback = new ModelRequestCallback<DataModel>() {
 594  
                             @Override
 595  
                             public void onModelReady(DataModel model) {
 596  0
                                     majorDisciplineService.getData((String)model.get("versionInfo/versionedFromId"), new AbstractCallback<Data>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
 597  
                         @Override
 598  
                         public void onSuccess(Data result) {
 599  0
                             super.onSuccess(result);
 600  0
                             comparisonModel.setRoot(result);
 601  0
                             reqDataModel.retrieveProgramRequirements(MajorProposalController.this, ProgramConstants.PROGRAM_MODEL_ID, new Callback<Boolean>() {
 602  
                                 @Override
 603  
                                 public void exec(Boolean result) {
 604  0
                                     if (result) {
 605  0
                                             reqDataModelComp.retrieveProgramRequirements(MajorProposalController.this, comparisonModelId, new Callback<Boolean>() {
 606  
                                             @Override
 607  
                                             public void exec(Boolean result) {
 608  0
                                                 if (result) {
 609  0
                                                     callback.onModelReady(comparisonModel);
 610  
                                                 }
 611  0
                                             }
 612  
                                         });
 613  
                                     }
 614  0
                                 }
 615  
                             });                    
 616  0
                         }
 617  
                         
 618  
                         @Override
 619  
                         public void onFailure(Throwable caught) {
 620  0
                             super.onFailure(caught);
 621  0
                             callback.onRequestFail(caught);
 622  0
                         }
 623  
                     });
 624  0
                         }
 625  
 
 626  
                             @Override
 627  
                             public void onRequestFail(Throwable cause) {
 628  0
                     GWT.log("Unable to retrieve comparison model", cause);
 629  0
                             }
 630  
                 };        
 631  
 
 632  0
                 if (viewContext.getIdType() == IdType.DOCUMENT_ID)
 633  0
                         loadProgramModelFromWorkflowId(comparisonModelCallback); 
 634  
                 else 
 635  0
                         super.loadModel(comparisonModelCallback);
 636  
         }        
 637  0
     }
 638  
 
 639  
     protected void createNewVersionAndLoadModel(final ModelRequestCallback<DataModel> callback, final ViewContext viewContext) {
 640  0
         Data data = new Data();                
 641  0
         Data versionData = new Data();
 642  0
         versionData.set(new Data.StringKey("versionIndId"), getViewContext().getId());
 643  0
         versionData.set(new Data.StringKey("versionComment"), "Major Disicpline Version");
 644  0
         data.set(new Data.StringKey("versionInfo"), versionData);
 645  
 
 646  0
         programRemoteService.saveData(data, new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
 647  
             @Override
 648  
             public void onSuccess(DataSaveResult result) {
 649  0
                 super.onSuccess(result);
 650  0
                 refreshModelAndView(result);
 651  
                 
 652  0
                 viewContext.setId(ProgramUtils.getProposalId(programModel));
 653  0
                 viewContext.setIdType(IdType.KS_KEW_OBJECT_ID);
 654  0
                 callback.onModelReady(programModel);
 655  0
                 eventBus.fireEvent(new ModelLoadedEvent(programModel));
 656  0
             }
 657  
 
 658  
             @Override
 659  
             public void onFailure(Throwable caught) {
 660  0
                 super.onFailure(caught);
 661  0
                 callback.onRequestFail(caught);
 662  0
             }
 663  
         });
 664  
 
 665  0
     }
 666  
 
 667  
     protected void loadProgramModelFromWorkflowId(final ModelRequestCallback<DataModel> callback){
 668  0
         workflowUtil.getDataIdFromWorkflowId(getViewContext().getId(), new KSAsyncCallback<String>(){
 669  
                         @Override
 670  
                         public void handleFailure(Throwable caught) {
 671  0
                 Window.alert("Error loading Proposal from Workflow Document: "+caught.getMessage());
 672  0
                         }
 673  
 
 674  
                         @Override
 675  
                         public void onSuccess(String proposalId) {
 676  
                                 //Create a new view Context and navigate if coming from action list
 677  0
                         ViewContext viewContext = new ViewContext();
 678  0
                 viewContext.setId(proposalId);
 679  0
                 getViewContext().setAttribute(StudentIdentityConstants.DOCUMENT_TYPE_NAME, LUConstants.PROPOSAL_TYPE_MAJOR_DISCIPLINE_MODIFY);
 680  0
                 viewContext.setIdType(IdType.KS_KEW_OBJECT_ID);
 681  0
                 Application.navigate(AppLocations.Locations.PROGRAM_PROPOSAL.getLocation(), viewContext);
 682  0
                         }
 683  
         });            
 684  0
     }
 685  
     
 686  
     private void doSave(final Callback<Boolean> okCallback) {
 687  0
         requestModel(new ModelRequestCallback<DataModel>() {
 688  
             @Override
 689  
             public void onModelReady(DataModel model) {
 690  0
                 MajorProposalController.this.updateModelFromCurrentView();
 691  0
                 model.validate(new Callback<List<ValidationResultInfo>>() {
 692  
                     @Override
 693  
                     public void exec(List<ValidationResultInfo> result) {
 694  0
                         boolean isSectionValid = isValid(result, true);
 695  0
                         if (isSectionValid) {
 696  0
                             saveData(okCallback);
 697  
                         } else {
 698  0
                             okCallback.exec(false);
 699  0
                             KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
 700  
                         }
 701  0
                     }
 702  
                 });
 703  
 
 704  0
             }
 705  
 
 706  
             @Override
 707  
             public void onRequestFail(Throwable cause) {
 708  0
                 GWT.log("Unable to retrieve model for validation and save", cause);
 709  0
             }
 710  
         });
 711  0
     }
 712  
 
 713  
     private void doCancel() {
 714  0
         showView(ProgramSections.SUMMARY);
 715  0
     }
 716  
 
 717  
     @Override
 718  
     protected void doSave() {
 719  0
         doSave(NO_OP_CALLBACK);
 720  0
     }
 721  
 
 722  
     private void saveData(final Callback<Boolean> okCallback) {
 723  0
         programRemoteService.saveData(programModel.getRoot(), new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_SAVINGDATA)) {
 724  
             @Override
 725  
             public void onSuccess(DataSaveResult result) {
 726  0
                 super.onSuccess(result);
 727  
 
 728  
                 //Clear warning states on field and any warnings stored in ApplicationContext;
 729  0
                 clearAllWarnings();
 730  0
                 Application.getApplicationContext().clearValidationWarnings();
 731  
                 
 732  0
                 List<ValidationResultInfo> validationResults = result.getValidationResults();
 733  0
                 Application.getApplicationContext().addValidationWarnings(validationResults);
 734  0
                 if (ValidatorClientUtils.hasErrors(validationResults)) {
 735  0
                     ProgramUtils.retrofitValidationResults(validationResults);
 736  0
                     isValid(validationResults, false, true);
 737  0
                     ProgramUtils.handleValidationErrorsForSpecializations(validationResults, programModel);
 738  
                     
 739  
                     //Clean up anything created by earlier code
 740  0
                     Data currentVariations = getDataProperty(ProgramConstants.VARIATIONS);
 741  
 
 742  0
                     existingVariationIds.clear();
 743  
 
 744  0
                     for (Iterator<Property> iter = currentVariations.iterator();iter.hasNext();) {
 745  0
                             Property prop = iter.next();
 746  0
                         String existingId = (String) ((Data) prop.getValue()).get(ProgramConstants.ID);
 747  0
                         if(existingId==null){
 748  0
                                 iter.remove();
 749  
                         }else{
 750  0
                                 existingVariationIds.add(existingId);
 751  
                         }
 752  0
                     }
 753  
                     
 754  0
                     okCallback.exec(false);
 755  0
                 } else {
 756  0
                         refreshModelAndView(result);
 757  0
                     if(workflowUtil != null){
 758  0
                         workflowUtil.refresh();
 759  
                     }                        
 760  0
                     resetFieldInteractionFlag();
 761  0
                     configurer.applyPermissions();
 762  0
                     handleSpecializations();
 763  0
                     throwAfterSaveEvent();
 764  0
                     HistoryManager.logHistoryChange();
 765  0
                     ViewContext viewContext = getViewContext();
 766  0
                     viewContext.setId(getStringProperty(ProgramConstants.ID));
 767  0
                     viewContext.setIdType(IdType.OBJECT_ID);
 768  
 
 769  0
                                     if (ValidatorClientUtils.hasWarnings(validationResults)){
 770  
                                             //Show validation warnings for major
 771  0
                                             isValid(result.getValidationResults(), false, true);                                            
 772  0
                                             KSNotifier.show("Saved with Warnings");
 773  
                                     } else {
 774  0
                         KSNotifier.show(getLabel(ProgramMsgConstants.COMMON_SUCCESSFULSAVE));
 775  
                                     }                                  
 776  
                     
 777  
                     // add to recently viewed now that we're sure to know the program's id
 778  0
                     ViewContext docContext = new ViewContext();
 779  0
                     docContext.setId(getStringProperty(ProgramConstants.ID));
 780  0
                     docContext.setIdType(IdType.OBJECT_ID);
 781  0
                     docContext.setAttribute(ProgramConstants.TYPE, ProgramConstants.MAJOR_LU_TYPE_ID + '/' + ProgramSections.PROGRAM_DETAILS_VIEW);
 782  0
                     RecentlyViewedHelper.addDocument(getProgramName(),
 783  
                     HistoryManager.appendContext(AppLocations.Locations.VIEW_PROGRAM.getLocation(), docContext));
 784  0
                         okCallback.exec(true);
 785  0
                         processCurrentView();                            
 786  
                 }
 787  0
             }
 788  
         }); 
 789  0
     }
 790  
 
 791  
     private void processCurrentView() {
 792  0
         Enum<?> currentView = getCurrentViewEnum();
 793  0
         if (currentView.name().equals(ProgramSections.VIEW_ALL.name())) {
 794  0
             HistoryManager.navigate(AppLocations.Locations.VIEW_PROGRAM.getLocation(), getViewContext());
 795  
         } else {
 796  0
             showView(currentView);
 797  
         }
 798  0
     }
 799  
 
 800  
     /**
 801  
      * Handles after save work for specializations.
 802  
      */
 803  
     private void handleSpecializations() {
 804  0
         String newVariationId = null;
 805  0
         Data variations = programModel.get(ProgramConstants.VARIATIONS);
 806  0
         for (Data.Property prop : variations) {
 807  0
             String varId = (String) ((Data) prop.getValue()).get(ProgramConstants.ID);
 808  0
             if (!existingVariationIds.contains(varId)) {
 809  0
                 newVariationId = varId;
 810  0
                 existingVariationIds.add(newVariationId);
 811  0
                 break;
 812  
             }
 813  0
         }
 814  0
         if (newVariationId != null) {
 815  0
             eventBus.fireEvent(new SpecializationCreatedEvent(newVariationId));
 816  
         } else {
 817  0
             eventBus.fireEvent(new SpecializationUpdateEvent(variations));
 818  
         }
 819  0
     }
 820  
 
 821  
     private void throwAfterSaveEvent() {
 822  0
         eventBus.fireEvent(new AfterSaveEvent(programModel, this));
 823  0
     }
 824  
 
 825  
     @Override
 826  
     public void onModelLoadedEvent() {
 827  0
         Enum<?> changeSection = ProgramRegistry.getSection();
 828  0
         if (changeSection != null) {
 829  0
             showView(changeSection);
 830  0
             ProgramRegistry.setSection(null);
 831  
         } else {
 832  0
             String id = getStringProperty(ProgramConstants.ID);
 833  0
             if (id == null) {
 834  0
                 showView(ProgramSections.PROGRAM_DETAILS_EDIT);
 835  
             } else {
 836  0
                 showView(ProgramSections.PROGRAM_PROPOSAL_EDIT);
 837  
             }
 838  
         }
 839  
 
 840  0
     }
 841  
 
 842  
         @Override
 843  
         public void beforeShow(final Callback<Boolean> onReadyCallback) {
 844  0
                 if(!initialized){
 845  0
                         Application.getApplicationContext().clearCrossConstraintMap(null);
 846  0
                         Application.getApplicationContext().clearPathToFieldMapping(null);
 847  
                 }
 848  
                 //Clear the parent path again
 849  0
                 Application.getApplicationContext().setParentPath("");
 850  0
                 super.beforeShow(onReadyCallback);                                                
 851  0
         }
 852  
 
 853  
         //Before show is called before the model is bound to the widgets. We need to update cross constraints after widget binding
 854  
         //This gets called twice which is not optimal
 855  
         @Override
 856  
         public <V extends Enum<?>> void showView(V viewType,
 857  
                         final Callback<Boolean> onReadyCallback) {
 858  0
                 Callback<Boolean> updateCrossConstraintsCallback = new Callback<Boolean>(){
 859  
                         public void exec(Boolean result) {
 860  0
                                 onReadyCallback.exec(result);
 861  0
                         for(HasCrossConstraints crossConstraint:Application.getApplicationContext().getCrossConstraints(null)){
 862  0
                                 crossConstraint.reprocessWithUpdatedConstraints();
 863  
                         }
 864  0
                         showWarnings();        
 865  0
                         }
 866  
         };
 867  0
                 super.showView(viewType, updateCrossConstraintsCallback);
 868  0
         }
 869  
 
 870  
         //Ensure that the managing bodies section view is updated before the user edits specializations
 871  
         @Override
 872  
         public void beforeViewChange(final Enum<?> viewChangingTo, final Callback<Boolean> okToChangeCallback){
 873  0
             final Callback<Boolean> reallyOkToChange = new Callback<Boolean>() {
 874  
 
 875  
             @Override
 876  
             public void exec(Boolean result) {
 877  0
                 if (result) {
 878  0
                     if (LUMViews.VARIATION_EDIT.equals(viewChangingTo)) {
 879  0
                         getView(ProgramSections.MANAGE_BODIES_EDIT, new Callback<View>() {
 880  
                             @Override
 881  
                             public void exec(final View view) {
 882  0
                                 if (view != null && view instanceof SectionView) {
 883  0
                                     requestModel(new ModelRequestCallback<DataModel>() {
 884  
                                         public void onModelReady(DataModel model) {
 885  0
                                             ((SectionView) view).updateWidgetData(model);
 886  0
                                             okToChangeCallback.exec(true);
 887  0
                                         }
 888  
 
 889  
                                         public void onRequestFail(Throwable cause) {
 890  0
                                             okToChangeCallback.exec(false);
 891  0
                                         }
 892  
                                     });
 893  
                                 } else {
 894  0
                                     okToChangeCallback.exec(true);
 895  
                                 }
 896  0
                             }
 897  
                         });
 898  
                     } else {
 899  0
                         okToChangeCallback.exec(true);
 900  
                     }
 901  
                 }
 902  0
             }
 903  
         };
 904  0
         super.beforeViewChange(viewChangingTo, reallyOkToChange);
 905  0
         this.showExport(isExportButtonActive()); // KSLAB-1916
 906  0
         }
 907  
 
 908  
     protected void setStatus() {
 909  0
         String modelProposalId = programModel.get(QueryPath.parse(proposalPath + "/id"));
 910  
 
 911  0
         if (modelProposalId != null && !modelProposalId.isEmpty()) {
 912  0
             String workflowId = programModel.get(QueryPath.parse(proposalPath + "/workflowId"));
 913  0
             proposalServiceAsync.getProposalByWorkflowId(workflowId, new KSAsyncCallback<ProposalInfo>() {
 914  
                 @Override
 915  
                 public void handleFailure(Throwable caught) {
 916  0
                     statusLabel.setText("Proposal status: Unknown");
 917  0
                 }
 918  
 
 919  
                 @Override
 920  
                 public void onSuccess(ProposalInfo result) {
 921  0
                     statusLabel.setText("Proposal status: " + result.getState());
 922  0
                 }
 923  
             });
 924  
         }
 925  0
     }
 926  
         
 927  
     public ProgramRequirementsDataModel getReqDataModel() {
 928  0
         return reqDataModel;
 929  
     }
 930  
 
 931  
     public ProgramRequirementsDataModel getReqDataModelComp() {
 932  0
         return reqDataModelComp;
 933  
     }
 934  
 
 935  
         @Override
 936  
         public void getMetadataForFinalState(final KSAsyncCallback<Metadata> callback) {
 937  
                 //Setup View Context
 938  0
                 String idType = null;
 939  0
                 String viewContextId = "";
 940  0
                 if(getViewContext().getIdType() != null){
 941  0
             idType = getViewContext().getIdType().toString();
 942  0
             viewContextId = getViewContext().getId();
 943  0
             if(getViewContext().getIdType()==IdAttributes.IdType.COPY_OF_OBJECT_ID){
 944  0
                     viewContextId = null;
 945  
             }
 946  
                 }
 947  0
                 HashMap<String, String> idAttributes = new HashMap<String, String>();
 948  0
                 if(idType != null){
 949  0
                         idAttributes.put(IdAttributes.ID_TYPE, idType);
 950  
                 }
 951  
 
 952  0
                 idAttributes.put(StudentIdentityConstants.DOCUMENT_TYPE_NAME, "kuali.proposal.type.majorDiscipline.modify");
 953  0
                 idAttributes.put(DtoConstants.DTO_STATE, "Draft");                                    
 954  0
                 idAttributes.put(DtoConstants.DTO_NEXT_STATE, "Active");
 955  0
                 idAttributes.put(DtoConstants.DTO_WORKFLOW_NODE, "Publication Review");
 956  
                 
 957  
                 //Get metadata and complete initializing the screen
 958  0
                 programRemoteService.getMetadata(viewContextId, idAttributes, new KSAsyncCallback<Metadata>(){
 959  
                         @Override
 960  
                         public void onSuccess(Metadata metadata) {
 961  
                                 //This is not being used on screens so removing from validation
 962  0
                                 metadata.getProperties().remove("orgCoreProgram"); 
 963  0
                                 callback.onSuccess(metadata);
 964  0
                         }
 965  
                 });
 966  0
         }
 967  
 
 968  
         @Override
 969  
         public void checkAuthorization(final AuthorizationCallback callbackLocatedOnBaseControllerClass) {
 970  
                 
 971  0
                 Map<String,String> attributes = new HashMap<String,String>();
 972  0
                 GWT.log("Attempting Auth Check.", null);
 973  0
                 if (programModel != null && programModel.getRoot() != null) {
 974  
                         //This is to handle the case where entry into the proposal screens is by clicking parent breadcrumb or 
 975  
                         //parent link from within specialization
 976  0
                         attributes.put(IdType.KS_KEW_OBJECT_ID.toString(), ProgramUtils.getProposalId(programModel));
 977  0
                     attributes.put(StudentIdentityConstants.DOCUMENT_TYPE_NAME, LUConstants.PROPOSAL_TYPE_MAJOR_DISCIPLINE_MODIFY);
 978  0
                 } else if ( (getViewContext().getId() != null) && (!"".equals(getViewContext().getId())) && getViewContext().getIdType() != null ) {
 979  0
                         if (getViewContext().getIdType() == IdType.KS_KEW_OBJECT_ID || getViewContext().getIdType() == IdType.DOCUMENT_ID){
 980  0
                                 attributes.put(getViewContext().getIdType().toString(), getViewContext().getId());
 981  
                         }
 982  
                 }
 983  0
                 programRemoteService.isAuthorized(getViewContext().getPermissionType(), attributes, new KSAsyncCallback<Boolean>(){
 984  
 
 985  
                         @Override
 986  
                         public void handleFailure(Throwable caught) {
 987  0
                                 callbackLocatedOnBaseControllerClass.isNotAuthorized("Error checking authorization.");
 988  0
                                 GWT.log("Error checking proposal authorization.", caught);
 989  0
                 Window.alert("Error Checking Proposal Authorization: "+caught.getMessage());
 990  0
                         }
 991  
 
 992  
                         @Override
 993  
                         public void onSuccess(Boolean result) {
 994  0
                                 GWT.log("Succeeded checking auth for permission type '" + getViewContext().getPermissionType().toString() + "' with result: " + result, null);
 995  0
                                 if (Boolean.TRUE.equals(result)) {
 996  0
                                         callbackLocatedOnBaseControllerClass.isAuthorized();
 997  
                                 }
 998  
                                 else {
 999  0
                                         callbackLocatedOnBaseControllerClass.isNotAuthorized("User is not authorized: " + getViewContext().getPermissionType().toString());
 1000  
                                 }
 1001  0
                         }
 1002  
             });
 1003  0
         }
 1004  
 
 1005  
 
 1006  
         @Override
 1007  
         public boolean isAuthorizationRequired() {
 1008  0
                 return true;
 1009  
         }
 1010  
 
 1011  
 
 1012  
         @Override
 1013  
         public void setAuthorizationRequired(boolean required) {
 1014  
                 //Does nothing at the momement
 1015  0
         }
 1016  
 
 1017  
     @Override
 1018  
     public ArrayList<ExportElement> getExportElementsFromView() {
 1019  0
         String viewName = null;
 1020  0
         String sectionTitle = null;
 1021  0
         View currentView = this.getCurrentView();
 1022  0
         if (currentView != null) {
 1023  
             
 1024  0
             ArrayList<ExportElement> exportElements = new ArrayList<ExportElement>();
 1025  0
             if (currentView != null && currentView instanceof Section) {
 1026  0
                 Section currentSection = (Section) currentView;
 1027  0
                 List<Section> nestedSections = currentSection.getSections();
 1028  0
                        for (int i = 0; i < nestedSections.size(); i++) {
 1029  0
                                ExportElement sectionExportItem = new ExportElement();
 1030  0
                                ArrayList<ExportElement> subList = null;
 1031  0
                                Section nestedSection = nestedSections.get(i);
 1032  0
                            if (nestedSection != null && nestedSection instanceof SectionView) {
 1033  0
                                    SectionView nestedSectionView = (SectionView) nestedSection;
 1034  0
                               viewName =  nestedSectionView.getName();
 1035  0
                               subList = new ArrayList<ExportElement>();
 1036  0
                         if (this.getCurrentViewEnum().equals(ProgramSections.SUMMARY)) {
 1037  0
                                    sectionExportItem.setSectionName(viewName);
 1038  
 
 1039  0
                                    List<Section> sectionList = nestedSectionView.getSections();
 1040  0
                                 for (int j = 0; j < sectionList.size(); j++) {
 1041  0
                                         if (sectionList.get(j) instanceof SummaryTableSection)
 1042  
                                         {        
 1043  0
                                                 SummaryTableSection tableSection = (SummaryTableSection) sectionList.get(j);
 1044  0
                                             ExportElement heading = new ExportElement();
 1045  0
                                             heading.setFieldLabel("");
 1046  0
                                             heading.setFieldValue(programModel.getModelName());
 1047  0
                                             heading.setFieldValue2(comparisonModel.getModelName());
 1048  0
                                             subList.add(heading);
 1049  0
                                             subList.addAll(ExportUtils.getDetailsForWidget(tableSection.getSummaryTable()));                                        
 1050  0
                                         } else if (sectionList.get(j) instanceof CollapsableSection)
 1051  
                                         {
 1052  0
                                                 List<Section> sectionColList = sectionList.get(j).getSections();
 1053  0
                                         for (int k = 0; k < sectionColList.size(); k++) {
 1054  0
                                                 SummaryTableSection tableSection = (SummaryTableSection) sectionColList.get(k);
 1055  0
                                                 ExportElement heading = new ExportElement();
 1056  0
                                                 heading.setFieldLabel("");
 1057  0
                                                 heading.setFieldValue(programModel.getModelName());
 1058  0
                                                 heading.setFieldValue2(comparisonModel.getModelName());
 1059  0
                                                 subList.add(heading);
 1060  0
                                                 subList.addAll(ExportUtils.getDetailsForWidget(tableSection.getSummaryTable()));                                        
 1061  
                                         }        
 1062  
                                         }        
 1063  
                                 }        
 1064  0
                         } else {         
 1065  0
                                    sectionTitle = nestedSectionView.getTitle();
 1066  0
                                    sectionExportItem.setSectionName(sectionTitle + " " + i + " - " + viewName);
 1067  0
                                    sectionExportItem.setViewName(sectionTitle + " " + i + " - " + viewName);
 1068  0
                                    subList = ExportUtils.getExportElementsFromView(nestedSectionView, subList, viewName, sectionTitle);
 1069  
                             }
 1070  0
                                if (subList != null && subList.size()> 0) {
 1071  0
                                        sectionExportItem.setSubset(subList);
 1072  0
                                        if (i == 0 && this.getCurrentViewEnum().equals(ProgramSections.SUMMARY))
 1073  0
                                                exportElements.add(sectionExportItem);
 1074  0
                                        exportElements.add(sectionExportItem);
 1075  
                                }        
 1076  
                     }        
 1077  
                        }
 1078  
             }
 1079  0
             return exportElements;           
 1080  
         } else {
 1081  
 //            logger.warn("ExportUtils.getExportElementsFromView controller currentView is null :" + this.getClass().getName());
 1082  
         }
 1083  0
         return null;    
 1084  
     }
 1085  
 
 1086  
     @Override
 1087  
     public String getExportTemplateName() {
 1088  0
         if (this.getCurrentViewEnum().equals(ProgramSections.SUMMARY))
 1089  0
                 return "proposal.template";
 1090  
 
 1091  0
         return "base.template";        
 1092  
     }
 1093  
 
 1094  
 }