1 package org.kuali.student.lum.program.client.credential.edit;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.kuali.student.r1.common.assembly.data.Data;
7 import org.kuali.student.r1.common.assembly.data.QueryPath;
8 import org.kuali.student.r2.common.dto.ValidationResultInfo;
9 import org.kuali.student.common.ui.client.application.Application;
10 import org.kuali.student.common.ui.client.application.ViewContext;
11 import org.kuali.student.common.ui.client.mvc.Callback;
12 import org.kuali.student.common.ui.client.mvc.DataModel;
13 import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
14 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
15 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
16 import org.kuali.student.common.ui.client.service.DataSaveResult;
17 import org.kuali.student.common.ui.client.validator.ValidatorClientUtils;
18 import org.kuali.student.common.ui.client.widgets.KSButton;
19 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
20 import org.kuali.student.common.ui.client.widgets.notification.KSNotification;
21 import org.kuali.student.common.ui.client.widgets.notification.KSNotifier;
22 import org.kuali.student.common.ui.shared.IdAttributes.IdType;
23 import org.kuali.student.lum.common.client.widgets.AppLocations;
24 import org.kuali.student.lum.program.client.ProgramConstants;
25 import org.kuali.student.lum.program.client.ProgramMsgConstants;
26 import org.kuali.student.lum.program.client.ProgramRegistry;
27 import org.kuali.student.lum.program.client.ProgramSections;
28 import org.kuali.student.lum.program.client.ProgramUtils;
29 import org.kuali.student.lum.program.client.credential.CredentialController;
30 import org.kuali.student.lum.program.client.events.AfterSaveEvent;
31 import org.kuali.student.lum.program.client.events.ChangeViewEvent;
32 import org.kuali.student.lum.program.client.events.MetadataLoadedEvent;
33 import org.kuali.student.lum.program.client.events.ModelLoadedEvent;
34 import org.kuali.student.lum.program.client.events.StateChangeEvent;
35 import org.kuali.student.lum.program.client.events.StoreRequirementIDsEvent;
36 import org.kuali.student.lum.program.client.events.UpdateEvent;
37 import org.kuali.student.lum.program.client.rpc.AbstractCallback;
38
39 import com.google.gwt.core.client.GWT;
40 import com.google.gwt.event.dom.client.ClickEvent;
41 import com.google.gwt.event.dom.client.ClickHandler;
42 import com.google.gwt.event.shared.HandlerManager;
43 import com.google.gwt.user.client.Window;
44
45
46
47
48 public class CredentialEditController extends CredentialController {
49
50 private final KSButton saveButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_SAVE));
51 private final KSButton cancelButton = new KSButton(getLabel(ProgramMsgConstants.COMMON_CANCEL), KSButtonAbstract.ButtonStyle.ANCHOR_LARGE_CENTERED);
52
53
54
55
56
57
58 public CredentialEditController(DataModel programModel, ViewContext viewContext, HandlerManager eventBus) {
59 super(programModel, viewContext, eventBus);
60 configurer = GWT.create(CredentialEditConfigurer.class);
61 bind();
62 }
63
64 @Override
65 protected void configureView() {
66 super.configureView();
67 if (!initialized) {
68 eventBus.fireEvent(new MetadataLoadedEvent(programModel.getDefinition(), this));
69 List<Enum<?>> excludedViews = new ArrayList<Enum<?>>();
70 excludedViews.add(ProgramSections.PROGRAM_REQUIREMENTS_EDIT);
71 excludedViews.add(ProgramSections.SUPPORTING_DOCUMENTS_EDIT);
72 excludedViews.add(ProgramSections.SUMMARY);
73 addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), saveButton, excludedViews);
74 addCommonButton(getLabel(ProgramMsgConstants.PROGRAM_MENU_SECTIONS), cancelButton, excludedViews);
75 initialized = true;
76 }
77 }
78
79 private void bind() {
80 saveButton.addClickHandler(new ClickHandler() {
81
82 @Override
83 public void onClick(ClickEvent event) {
84 doSave();
85 }
86 });
87 cancelButton.addClickHandler(new ClickHandler() {
88
89 @Override
90 public void onClick(ClickEvent event) {
91 doCancel();
92 }
93 });
94 eventBus.addHandler(StoreRequirementIDsEvent.TYPE, new StoreRequirementIDsEvent.Handler() {
95 @Override
96 public void onEvent(StoreRequirementIDsEvent event) {
97 List<String> ids = event.getProgramRequirementIds();
98
99 programModel.set(QueryPath.parse(ProgramConstants.PROGRAM_REQUIREMENTS), new Data());
100 Data programRequirements = getDataProperty(ProgramConstants.PROGRAM_REQUIREMENTS);
101
102 if (programRequirements == null) {
103 Window.alert("Cannot find program requirements in data model.");
104 GWT.log("Cannot find program requirements in data model", null);
105 return;
106 }
107
108 for (String id : ids) {
109 programRequirements.add(id);
110 }
111 doSave();
112 }
113 });
114 eventBus.addHandler(ChangeViewEvent.TYPE, new ChangeViewEvent.Handler() {
115 @Override
116 public void onEvent(ChangeViewEvent event) {
117 showView(event.getViewToken());
118 }
119 });
120 eventBus.addHandler(UpdateEvent.TYPE, new UpdateEvent.Handler() {
121 @Override
122 public void onEvent(UpdateEvent event) {
123 doSave(event.getOkCallback());
124 }
125 });
126 eventBus.addHandler(StateChangeEvent.TYPE, new StateChangeEvent.Handler() {
127 @Override
128 public void onEvent(final StateChangeEvent event) {
129 programModel.validateNextState(new Callback<List<ValidationResultInfo>>() {
130 @Override
131 public void exec(List<ValidationResultInfo> result) {
132 boolean isSectionValid = isValid(result, true);
133 if (isSectionValid) {
134 Callback<Boolean> callback = new Callback<Boolean>() {
135 @Override
136 public void exec(Boolean result) {
137 if (result) {
138 reloadMetadata = true;
139 loadMetadata(new Callback<Boolean>() {
140 @Override
141 public void exec(Boolean result) {
142 if (result) {
143 ProgramUtils.syncMetadata(configurer, programModel.getDefinition());
144 HistoryManager.navigate(AppLocations.Locations.VIEW_BACC_PROGRAM.getLocation(), context);
145 }
146 }
147 });
148 }
149 }
150 };
151 updateState(event.getProgramStatus().getValue(), callback);
152 } else {
153 KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
154 }
155 }
156 });
157 }
158 });
159 }
160
161 private void doCancel() {
162 showView(ProgramSections.SUMMARY);
163 }
164
165 @Override
166 protected void doSave() {
167 doSave(NO_OP_CALLBACK);
168 }
169
170 private void doSave(final Callback<Boolean> okCallback) {
171 requestModel(new ModelRequestCallback<DataModel>() {
172 @Override
173 public void onModelReady(DataModel model) {
174 CredentialEditController.this.updateModelFromCurrentView();
175 model.validate(new Callback<List<ValidationResultInfo>>() {
176 @Override
177 public void exec(List<ValidationResultInfo> result) {
178 boolean isSectionValid = isValid(result, true);
179 if (isSectionValid) {
180 saveData(okCallback);
181 } else {
182 okCallback.exec(false);
183 KSNotifier.add(new KSNotification("Unable to save, please check fields for errors.", false, true, 5000));
184 }
185 }
186 });
187
188 }
189
190 @Override
191 public void onRequestFail(Throwable cause) {
192 GWT.log("Unable to retrieve model for validation and save", cause);
193 }
194 });
195 }
196
197 private void saveData(final Callback<Boolean> okCallback) {
198 programRemoteService.saveData(programModel.getRoot(), new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_SAVINGDATA)) {
199 @Override
200 public void onSuccess(DataSaveResult result) {
201 super.onSuccess(result);
202
203 clearAllWarnings();
204 Application.getApplicationContext().clearValidationWarnings();
205
206 List<ValidationResultInfo> validationResults = result.getValidationResults();
207 Application.getApplicationContext().addValidationWarnings(validationResults);
208
209 if (ValidatorClientUtils.hasErrors(validationResults)) {
210 isValid(result.getValidationResults(), false, true);
211 StringBuilder msg = new StringBuilder();
212 for (ValidationResultInfo vri : result.getValidationResults()) {
213 if(!msg.toString().contains(vri.getMessage()))
214 msg.append(vri.getMessage() + " ");
215 }
216 if (msg.length() > 0)
217 KSNotifier.add(new KSNotification(msg.toString(), false, true, 5000));
218 okCallback.exec(false);
219 } else {
220 refreshModelAndView(result);
221 resetFieldInteractionFlag();
222 throwAfterSaveEvent();
223 if (ProgramSections.getViewForUpdate().contains(getCurrentViewEnum().name())) {
224 showView(getCurrentViewEnum());
225 }
226 HistoryManager.logHistoryChange();
227
228 if (ValidatorClientUtils.hasWarnings(validationResults)){
229 isValid(result.getValidationResults(), false, true);
230 KSNotifier.show("Saved with Warnings");
231 } else {
232 KSNotifier.show(getLabel(ProgramMsgConstants.COMMON_SUCCESSFULSAVE));
233 }
234
235 okCallback.exec(true);
236 }
237 }
238 });
239 }
240
241 @Override
242 protected void loadModel(ModelRequestCallback<DataModel> callback) {
243 ViewContext viewContext = getViewContext();
244 if (viewContext.getIdType() == IdType.COPY_OF_OBJECT_ID) {
245 createNewVersionAndLoadModel(callback, viewContext);
246 } else {
247 super.loadModel(callback);
248 }
249 }
250
251 protected void createNewVersionAndLoadModel(final ModelRequestCallback<DataModel> callback, final ViewContext viewContext) {
252 Data data = new Data();
253 Data versionData = new Data();
254 versionData.set(new Data.StringKey("versionIndId"), getViewContext().getId());
255 versionData.set(new Data.StringKey("versionComment"), "Credential Program Version");
256 data.set(new Data.StringKey("version"), versionData);
257
258 programRemoteService.saveData(data, new AbstractCallback<DataSaveResult>(getLabel(ProgramMsgConstants.COMMON_RETRIEVINGDATA)) {
259 @Override
260 public void onSuccess(DataSaveResult result) {
261 super.onSuccess(result);
262 programModel.setRoot(result.getValue());
263 viewContext.setIdType(IdType.OBJECT_ID);
264 viewContext.setId((String) programModel.get(ProgramConstants.ID));
265 setHeaderTitle();
266 setStatus();
267 callback.onModelReady(programModel);
268 eventBus.fireEvent(new ModelLoadedEvent(programModel));
269 }
270
271 @Override
272 public void onFailure(Throwable caught) {
273 super.onFailure(caught);
274 callback.onRequestFail(caught);
275 }
276 });
277
278 }
279
280 private void throwAfterSaveEvent() {
281 eventBus.fireEvent(new AfterSaveEvent(programModel, this));
282 }
283
284 @Override
285 public void onModelLoadedEvent() {
286 Enum<?> changeSection = ProgramRegistry.getSection();
287 if (changeSection != null) {
288 showView(changeSection);
289 ProgramRegistry.setSection(null);
290 } else {
291 String id = getStringProperty(ProgramConstants.ID);
292 if (id == null) {
293 showView(ProgramSections.PROGRAM_DETAILS_EDIT);
294 } else {
295 showView(ProgramSections.SUMMARY);
296 }
297 }
298 }
299
300 @Override
301 public void beforeShow(final Callback<Boolean> onReadyCallback) {
302 if(!initialized){
303 Application.getApplicationContext().clearCrossConstraintMap(null);
304 Application.getApplicationContext().clearPathToFieldMapping(null);
305 }
306
307 Application.getApplicationContext().setParentPath("");
308 super.beforeShow(onReadyCallback);
309 }
310
311
312
313 @Override
314 public <V extends Enum<?>> void showView(V viewType,
315 final Callback<Boolean> onReadyCallback) {
316 Callback<Boolean> updateCrossConstraintsCallback = new Callback<Boolean>(){
317 public void exec(Boolean result) {
318 onReadyCallback.exec(result);
319 for(HasCrossConstraints crossConstraint:Application.getApplicationContext().getCrossConstraints(null)){
320 crossConstraint.reprocessWithUpdatedConstraints();
321 }
322 showWarnings();
323 }
324 };
325 super.showView(viewType, updateCrossConstraintsCallback);
326 }
327 }