1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.student.enrollment.class2.courseoffering.controller;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.UnhandledException;
21 import org.apache.log4j.Logger;
22 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23 import org.kuali.rice.krad.util.GlobalVariables;
24 import org.kuali.rice.krad.util.KRADConstants;
25 import org.kuali.rice.krad.web.controller.UifControllerBase;
26 import org.kuali.rice.krad.web.form.UifFormBase;
27 import org.kuali.rice.krms.util.KRMSConstants;
28 import org.kuali.student.common.uif.util.GrowlIcon;
29 import org.kuali.student.common.uif.util.KSUifUtils;
30 import org.kuali.student.enrollment.class2.courseoffering.dto.SocRolloverResultItemWrapper;
31 import org.kuali.student.enrollment.class2.courseoffering.form.CourseOfferingRolloverManagementForm;
32 import org.kuali.student.enrollment.class2.courseoffering.service.CourseOfferingViewHelperService;
33 import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingConstants;
34 import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
35 import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
36 import org.kuali.student.enrollment.courseofferingset.dto.SocInfo;
37 import org.kuali.student.enrollment.courseofferingset.dto.SocRolloverResultInfo;
38 import org.kuali.student.enrollment.courseofferingset.dto.SocRolloverResultItemInfo;
39 import org.kuali.student.enrollment.courseofferingset.service.CourseOfferingSetService;
40 import org.kuali.student.r2.common.dto.ContextInfo;
41 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
42 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
43 import org.kuali.student.r2.common.exceptions.MissingParameterException;
44 import org.kuali.student.r2.common.exceptions.OperationFailedException;
45 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
46 import org.kuali.student.r2.common.util.ContextUtils;
47 import org.kuali.student.r2.common.util.constants.CourseOfferingServiceConstants;
48 import org.kuali.student.r2.common.util.constants.CourseOfferingSetServiceConstants;
49 import org.kuali.student.r2.common.util.date.DateFormatters;
50 import org.kuali.student.r2.core.acal.dto.ExamPeriodInfo;
51 import org.kuali.student.r2.core.acal.dto.TermInfo;
52 import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
53 import org.kuali.student.r2.core.class1.state.dto.StateInfo;
54 import org.kuali.student.r2.core.class1.state.service.StateService;
55 import org.kuali.student.r2.core.constants.AcademicCalendarServiceConstants;
56 import org.kuali.student.r2.core.constants.AtpServiceConstants;
57 import org.kuali.student.r2.core.constants.StateServiceConstants;
58 import org.springframework.stereotype.Controller;
59 import org.springframework.validation.BindingResult;
60 import org.springframework.web.bind.annotation.ModelAttribute;
61 import org.springframework.web.bind.annotation.RequestMapping;
62 import org.springframework.web.bind.annotation.RequestMethod;
63 import org.springframework.web.servlet.ModelAndView;
64
65 import javax.servlet.http.HttpServletRequest;
66 import javax.servlet.http.HttpServletResponse;
67 import javax.xml.namespace.QName;
68 import java.util.Date;
69 import java.util.Formatter;
70 import java.util.List;
71 import java.util.Locale;
72 import java.util.Map;
73 import java.util.concurrent.CopyOnWriteArrayList;
74
75
76
77
78
79
80 @Controller
81 @RequestMapping(value = "/courseOfferingRollover")
82 public class CourseOfferingRolloverController extends UifControllerBase {
83 private CourseOfferingViewHelperService viewHelperService;
84 private CourseOfferingSetService socService;
85 private CourseOfferingService coService;
86 private StateService stateService;
87 private AcademicCalendarService acalService;
88
89 private static final Logger LOGGER = Logger.getLogger(CourseOfferingRolloverController.class);
90 public static final String ROLLOVER_DETAILS_PAGEID = "selectTermForRolloverDetails";
91
92 @Override
93 protected UifFormBase createInitialForm(@SuppressWarnings("unused") HttpServletRequest request) {
94 return new CourseOfferingRolloverManagementForm();
95 }
96
97 @Override
98 @RequestMapping(method = RequestMethod.GET, params = "methodToCall=start")
99 public ModelAndView start(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
100 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) {
101 if (!(form instanceof CourseOfferingRolloverManagementForm)) {
102 throw new RuntimeException("Form object passed into start method was not of expected type CourseOfferingRolloverManagementForm. Got " + form.getClass().getSimpleName());
103 }
104 CourseOfferingRolloverManagementForm theForm = (CourseOfferingRolloverManagementForm) form;
105
106
107
108 if (form.getView() != null) {
109 String methodToCall = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
110 checkViewAuthorization(theForm, methodToCall);
111 }
112
113 Map paramMap = request.getParameterMap();
114 if (paramMap.containsKey("pageId")) {
115 String pageId = ((String[]) paramMap.get("pageId"))[0];
116 if (pageId.equals("selectTermsForRollover")) {
117 return _startPerformRollover(form, result, request, response);
118 } else if (pageId.equals("releaseToDepts")) {
119 return _startReleaseToDepts(theForm, result, request, response);
120 } else if (pageId.equals("selectTermForRolloverDetails")) {
121 return _startRolloverDetails(form, result, request, response);
122 }
123 }
124 return getUIFModelAndView(theForm);
125 }
126
127 private ModelAndView _startPerformRollover(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
128 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) {
129 CourseOfferingRolloverManagementForm theForm = (CourseOfferingRolloverManagementForm) form;
130 LOGGER.info("startPerformRollover");
131 return getUIFModelAndView(theForm);
132 }
133
134 private ModelAndView _startRolloverDetails(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
135 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) {
136 CourseOfferingRolloverManagementForm theForm = (CourseOfferingRolloverManagementForm) form;
137 LOGGER.info("startRolloverDetails");
138 String rolloverTerm = theForm.getRolloverTargetTermCode();
139
140 try {
141 if (rolloverTerm != null && !"".equals(rolloverTerm)) {
142 return showRolloverResults(theForm, result, request, response);
143 }
144 } catch (Exception ex) {
145 return getUIFModelAndView(theForm);
146 }
147
148 return getUIFModelAndView(theForm);
149 }
150
151 private ModelAndView _startReleaseToDepts(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
152 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) {
153 LOGGER.info("startReleaseToDepts");
154 form.computeReleaseToDeptsDisabled();
155 return getUIFModelAndView(form);
156 }
157
158 @RequestMapping(params = "methodToCall=goTargetTerm")
159 public ModelAndView goTargetTerm(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
160 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
161 CourseOfferingViewHelperService helper = getViewHelperService(form);
162
163 String targetTermCd = form.getTargetTermCode();
164 String sourceTermCd = form.getSourceTermCode();
165 List<TermInfo> targetTermsByCode = helper.findTermByTermCode(targetTermCd);
166 List<TermInfo> sourceTermsByCode = helper.findTermByTermCode(sourceTermCd);
167
168
169 if (sourceTermsByCode.isEmpty()) {
170 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
171 form.setIsRolloverButtonDisabled(true);
172 return getUIFModelAndView(form);
173 }
174 if (targetTermsByCode.isEmpty()) {
175 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.targetTerm.inValid");
176 form.setIsRolloverButtonDisabled(true);
177 return getUIFModelAndView(form);
178 }
179
180 TermInfo targetTerm = helper.findTermByTermCode(targetTermCd).get(0);
181 TermInfo sourceTerm = helper.findTermByTermCode(sourceTermCd).get(0);
182 boolean likeTerms = sourceTerm.getTypeKey().equals(targetTerm.getTypeKey());
183 boolean sourcePrecedesTarget = sourceTerm.getStartDate().before(targetTerm.getStartDate());
184 if (!likeTerms) {
185 GlobalVariables.getMessageMap().putError("targetTermCode", "error.likeTerms.validation");
186 form.setIsRolloverButtonDisabled(true);
187 return getUIFModelAndView(form);
188 } else if (!sourcePrecedesTarget) {
189 GlobalVariables.getMessageMap().putError("targetTermCode", "error.years.validation");
190 form.setIsRolloverButtonDisabled(true);
191 return getUIFModelAndView(form);
192 }
193
194 List<TermInfo> termList = helper.findTermByTermCode(form.getTargetTermCode());
195 int firstTerm = 0;
196 if (termList != null && termList.size() == 1) {
197
198 List<String> coIds = this._getCourseOfferingService().getCourseOfferingIdsByTerm(termList.get(firstTerm).getId(), true, new ContextInfo());
199 if (!coIds.isEmpty()) {
200
201 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.rollover.targetTermExists");
202 return getUIFModelAndView(form);
203 }
204
205 TermInfo matchingTerm = termList.get(firstTerm);
206 String targetTermCode = matchingTerm.getCode();
207 form.setDisplayedTargetTermCode(targetTermCode);
208
209 Date startDate = matchingTerm.getStartDate();
210 String startDateStr = DateFormatters.COURSE_OFFERING_VIEW_HELPER_DATE_FORMATTER.format(startDate);
211 form.setTargetTermStartDate(startDateStr);
212
213 Date endDate = matchingTerm.getEndDate();
214 String endDateStr = DateFormatters.COURSE_OFFERING_VIEW_HELPER_DATE_FORMATTER.format(endDate);
215 form.setTargetTermEndDate(endDateStr);
216 form.setTargetTerm(matchingTerm);
217 form.setIsRolloverButtonDisabled(false);
218 } else {
219 form.setTargetTerm(null);
220 form.resetForm();
221 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.targetTerm.inValid");
222 }
223 return getUIFModelAndView(form);
224 }
225
226 @RequestMapping(params = "methodToCall=goSourceTerm")
227 public ModelAndView goSourceTerm(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
228 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
229 if (form.getSourceTermCode().isEmpty()) {
230 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
231 form.setIsRolloverButtonDisabled(true);
232 return getUIFModelAndView(form);
233 }
234 CourseOfferingViewHelperService helper = getViewHelperService(form);
235 List<TermInfo> termList = helper.findTermByTermCode(form.getSourceTermCode());
236 if (termList != null && termList.size() == 1) {
237 int firstTerm = 0;
238
239 TermInfo matchingTerm = termList.get(firstTerm);
240 String sourceTermCode = matchingTerm.getCode();
241
242 boolean sourceTermHasSoc = helper.termHasSoc(matchingTerm.getId(), form);
243 if (!sourceTermHasSoc) {
244 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.rollover.sourceTerm.noSoc");
245 form.setIsRolloverButtonDisabled(true);
246 return getUIFModelAndView(form);
247 }
248 form.setDisplayedSourceTermCode(sourceTermCode);
249
250 Date startDate = matchingTerm.getStartDate();
251 String startDateStr = DateFormatters.COURSE_OFFERING_VIEW_HELPER_DATE_FORMATTER.format(startDate);
252 form.setSourceTermStartDate(startDateStr);
253
254 Date endDate = matchingTerm.getEndDate();
255 String endDateStr = DateFormatters.COURSE_OFFERING_VIEW_HELPER_DATE_FORMATTER.format(endDate);
256 form.setSourceTermEndDate(endDateStr);
257 form.setSourceTerm(matchingTerm);
258 form.setIsGoSourceButtonDisabled(false);
259 } else {
260 form.setTargetTerm(null);
261 form.resetForm();
262 GlobalVariables.getMessageMap().putError("soucrceTermCode", "error.courseoffering.sourceTerm.inValid");
263 }
264 return getUIFModelAndView(form);
265 }
266
267 private boolean validateSourceTargetTerms(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form) throws Exception {
268 String targetTermCd = form.getTargetTermCode();
269 String sourceTermCd = form.getSourceTermCode();
270
271 if (sourceTermCd==null || sourceTermCd.isEmpty()) {
272 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
273 return false;
274 }
275 if (targetTermCd==null || targetTermCd.isEmpty()) {
276 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.sourceTerm.inValid");
277 return false;
278 }
279
280 CourseOfferingViewHelperService helper = getViewHelperService(form);
281 List<TermInfo> targetTermsByCode = helper.findTermByTermCode(targetTermCd);
282 List<TermInfo> sourceTermsByCode = helper.findTermByTermCode(sourceTermCd);
283
284 if (sourceTermsByCode==null || sourceTermsByCode.isEmpty()) {
285 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
286 return false;
287 }
288 if (targetTermsByCode==null || targetTermsByCode.isEmpty()) {
289 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.targetTerm.inValid");
290 return false;
291 }
292
293
294 int firstTerm = 0;
295 List<TermInfo> targetSubTermsByCode = _getAcalService().getIncludedTermsInTerm(targetTermsByCode.get(firstTerm).getId(), new ContextInfo());
296 List<TermInfo> sourceSubTermsByCode =_getAcalService().getIncludedTermsInTerm(sourceTermsByCode.get(firstTerm).getId(), new ContextInfo());
297
298 if (targetSubTermsByCode != null && targetSubTermsByCode.size() > 0) {
299 for (TermInfo targetSubTerm : targetSubTermsByCode) {
300 if(!StringUtils.equals(AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, targetSubTerm.getStateKey())) {
301 GlobalVariables.getMessageMap().putError("targetTermCode", "error.rollover.targetTerm.notOfficial");
302 form.setSourceTermInfoDisplay(getTermDisplayString(targetTermsByCode.get(firstTerm).getId(), targetTermsByCode.get(firstTerm)));
303 form.setTargetTermInfoDisplay(getTermDisplayString(sourceTermsByCode.get(firstTerm).getId(), sourceTermsByCode.get(firstTerm)));
304 return false;
305 }
306 }
307 }
308
309 if (sourceSubTermsByCode != null && sourceSubTermsByCode.size() > 0) {
310 for (TermInfo sourceSubTerm : sourceSubTermsByCode) {
311 if(!StringUtils.equals(AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, sourceSubTerm.getStateKey())) {
312 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.rollover.sourceTerm.notOfficial");
313 form.setSourceTermInfoDisplay(getTermDisplayString(targetTermsByCode.get(firstTerm).getId(), targetTermsByCode.get(firstTerm)));
314 form.setTargetTermInfoDisplay(getTermDisplayString(sourceTermsByCode.get(firstTerm).getId(), sourceTermsByCode.get(firstTerm)));
315 return false;
316 }
317 }
318 }
319
320 boolean sourceTermValid = sourceTermsByCode.size() == 1;
321 boolean targetTermValid = targetTermsByCode.size() == 1;
322
323 if (sourceTermValid && targetTermValid) {
324 TermInfo targetTerm = targetTermsByCode.get(firstTerm);
325 TermInfo sourceTerm = sourceTermsByCode.get(firstTerm);
326
327
328 boolean sourceTermHasSoc = helper.termHasSoc(sourceTerm.getId(), form);
329 if (!sourceTermHasSoc) {
330 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.rollover.sourceTerm.noSoc");
331 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
332 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
333 return false;
334 }
335 form.setSourceTerm(sourceTerm);
336
337
338 if(!StringUtils.equals(AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, targetTerm.getStateKey())) {
339 GlobalVariables.getMessageMap().putError("targetTermCode", "error.rollover.targetTerm.notOfficial");
340 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
341 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
342 return false;
343 }
344
345
346 boolean likeTerms = sourceTerm.getTypeKey().equals(targetTerm.getTypeKey());
347 boolean sourcePrecedesTarget = sourceTerm.getStartDate().before(targetTerm.getStartDate());
348 if (!likeTerms) {
349 GlobalVariables.getMessageMap().putError("targetTermCode", "error.likeTerms.validation");
350 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
351 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
352 return false;
353 } else if (!sourcePrecedesTarget) {
354 GlobalVariables.getMessageMap().putError("targetTermCode", "error.years.validation");
355 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
356 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
357 return false;
358 }
359
360
361 List<String> coIds = this._getCourseOfferingService().getCourseOfferingIdsByTerm(targetTermsByCode.get(firstTerm).getId(), true, new ContextInfo());
362 if (!coIds.isEmpty()) {
363
364 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.rollover.targetTermExists");
365 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
366 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
367 return false;
368 }
369 form.setTargetTerm(targetTerm);
370 } else {
371 form.setTargetTerm(null);
372 form.setSourceTerm(null);
373 form.resetForm();
374
375 if (!sourceTermValid && !targetTermValid) {
376 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
377 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.targetTerm.inValid");
378 } else if (sourceTermValid && !targetTermValid) {
379 TermInfo sourceTerm = sourceTermsByCode.get(firstTerm);
380 GlobalVariables.getMessageMap().putError("targetTermCode", "error.courseoffering.targetTerm.inValid");
381 form.setSourceTermInfoDisplay(getTermDisplayString(sourceTerm.getId(), sourceTerm));
382 } else if (!sourceTermValid && targetTermValid) {
383 TermInfo targetTerm = targetTermsByCode.get(firstTerm);
384 GlobalVariables.getMessageMap().putError("sourceTermCode", "error.courseoffering.sourceTerm.inValid");
385 form.setTargetTermInfoDisplay(getTermDisplayString(targetTerm.getId(), targetTerm));
386 }
387 }
388
389 return true;
390
391 }
392 @RequestMapping(params = "methodToCall=performRollover")
393 public ModelAndView performRollover(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
394 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
395 if (!validateSourceTargetTerms(form)) {
396 form.getDialogManager().removeDialog(CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG);
397 return getUIFModelAndView(form);
398 }
399
400 CourseOfferingViewHelperService helper = getViewHelperService (form);
401
402 if (form.getSourceTerm() == null || form.getTargetTerm() == null) {
403 form.setStatusField("(setUp) Source/target term objects appear to be missing");
404 return getUIFModelAndView(form);
405 }
406 form.setStatusField("");
407 String sourceTermId = form.getSourceTerm().getId();
408 String targetTermId = form.getTargetTerm().getId();
409
410 if (!helper.termHasExamPeriod(targetTermId)) {
411 if (!hasDialogBeenAnswered(CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG, form)) {
412
413 form.setLightboxScript("openLightboxOnLoad('" + CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG + "');");
414 form.getDialogManager().addDialog(CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG, form.getMethodToCall());
415 return getUIFModelAndView(form);
416 } else {
417 boolean continueWithoutExams = getBooleanDialogResponse(CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG, form, request, response);
418 form.getDialogManager().removeDialog(CourseOfferingSetServiceConstants.NO_EXAM_PERIOD_WARNING_DIALOG);
419 if (!continueWithoutExams) {
420 return getUIFModelAndView(form);
421 }
422 }
423 }
424
425 boolean success = helper.performRollover(sourceTermId, targetTermId, form);
426 if (success) {
427 form.setRolloverTargetTermCode(form.getTargetTermCode());
428 showRolloverResults(form, result, request, response);
429
430 return start(form, result, request, response);
431 } else {
432
433 return getUIFModelAndView(form);
434 }
435 }
436
437 @RequestMapping(params = "methodToCall=performReverseRollover")
438 public ModelAndView performReverseRollover(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
439 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
440 CourseOfferingViewHelperService helper = getViewHelperService(form);
441 if (form.getSourceTerm() == null || form.getTargetTerm() == null) {
442 form.setStatusField("(cleanUp) Source/target term objects appear to be missing");
443 return getUIFModelAndView(form);
444 }
445 form.setStatusField("");
446
447 String sourceTermId = form.getSourceTerm().getId();
448 String targetTermId = form.getTargetTerm().getId();
449 SocRolloverResultInfo info = helper.performReverseRollover(sourceTermId, targetTermId, form);
450 if (info != null) {
451 form.setStatusField("Num items processed: " + info.getItemsProcessed());
452 }
453 return getUIFModelAndView(form);
454 }
455
456 public CourseOfferingViewHelperService getViewHelperService(CourseOfferingRolloverManagementForm rolloverForm) {
457 if (viewHelperService == null) {
458 if (rolloverForm.getView().getViewHelperServiceClass() != null) {
459 viewHelperService = (CourseOfferingViewHelperService) rolloverForm.getView().getViewHelperService();
460 } else {
461 viewHelperService = (CourseOfferingViewHelperService) rolloverForm.getPostedView().getViewHelperService();
462 }
463 }
464 return viewHelperService;
465 }
466
467 private void _disableReleaseToDeptsIfNeeded(CourseOfferingViewHelperService helper, String targetTermId,
468 CourseOfferingRolloverManagementForm form) {
469 SocInfo socInfo = helper.getMainSoc(targetTermId);
470 if (socInfo == null) {
471
472 form.setReleaseToDeptsInvalidTerm(true);
473 } else {
474 String stateKey = socInfo.getStateKey();
475 if (!CourseOfferingSetServiceConstants.DRAFT_SOC_STATE_KEY.equals(stateKey)) {
476
477 form.setSocReleasedToDepts(true);
478 } else {
479 form.setSocReleasedToDepts(false);
480 }
481 }
482 }
483
484 private String _computeRolloverDuration(Date dateInitiated, Date dateCompleted) {
485 long diffInMillis = dateCompleted.getTime() - dateInitiated.getTime();
486 long diffInSeconds = diffInMillis / 1000;
487 int minutes = (int) (diffInSeconds / 60);
488 int seconds = (int) (diffInSeconds % 60);
489 int hours = minutes / 60;
490 minutes = minutes % 60;
491 String result = seconds + "s";
492 if (minutes > 0 || hours > 0) {
493 result = minutes + "m " + result;
494 }
495 if (hours > 0) {
496 result = hours + "h " + result;
497 }
498 return result;
499 }
500
501 private String _createPlural(int count) {
502 return count == 1 ? "" : "s";
503 }
504
505 private String _createStatusString(SocRolloverResultInfo socRolloverResultInfo) {
506 String status = "";
507 String stateKey = socRolloverResultInfo.getStateKey();
508 if (CourseOfferingSetServiceConstants.SUBMITTED_RESULT_STATE_KEY.equals(stateKey) ||
509 CourseOfferingSetServiceConstants.RUNNING_RESULT_STATE_KEY.equals(stateKey)) {
510 status = " (in progress)";
511 } else if (CourseOfferingSetServiceConstants.ABORTED_RESULT_STATE_KEY.equals(stateKey)) {
512 status = " (aborted)";
513 }
514 return status;
515 }
516
517 private void _setStatus(String stateKey, CourseOfferingRolloverManagementForm form) {
518 if (CourseOfferingSetServiceConstants.FINISHED_RESULT_STATE_KEY.equals(stateKey)) {
519 form.setStatusField("Finished");
520 form.setRolloverCompleted(true);
521 } else if (CourseOfferingSetServiceConstants.RUNNING_RESULT_STATE_KEY.equals(stateKey) ||
522 CourseOfferingSetServiceConstants.SUBMITTED_RESULT_STATE_KEY.equals(stateKey)) {
523 form.setStatusField("In Progress");
524 form.setRolloverCompleted(false);
525 } else if (CourseOfferingSetServiceConstants.ABORTED_RESULT_STATE_KEY.equals(stateKey)) {
526 form.setRolloverCompleted(true);
527 }
528 }
529
530 private void _displayRolloverInfo(SocInfo socInfo, SocRolloverResultInfo socRolloverResultInfo,
531 CourseOfferingRolloverManagementForm form, CourseOfferingViewHelperService helper,
532 String stateKey, String targetTermId) {
533 if (socInfo != null) {
534
535 String friendlySourceTermDesc = helper.getTermDesc(socInfo.getTermId());
536 form.setRolloverSourceTermDesc(friendlySourceTermDesc);
537 String friendlyTargetTermDesc = helper.getTermDesc(targetTermId);
538 form.setRolloverTargetTermDesc(friendlyTargetTermDesc);
539 }
540 Date dateInitiated = socRolloverResultInfo.getDateInitiated();
541 String startDateStr = helper.formatDateAndTime(dateInitiated);
542 form.setDateInitiated(startDateStr);
543
544 if (socRolloverResultInfo.getCourseOfferingsCreated() == null || socRolloverResultInfo.getCourseOfferingsCreated().toString().length() < 1) {
545 Integer temp = socRolloverResultInfo.getItemsExpected() - socRolloverResultInfo.getItemsProcessed();
546 String plural = _createPlural(temp);
547 form.setCourseOfferingsAllowed(socRolloverResultInfo.getItemsProcessed() + " transitioned with " + temp + " exception" + plural);
548 } else {
549
550 String plural = _createPlural(socRolloverResultInfo.getCourseOfferingsSkipped());
551 form.setCourseOfferingsAllowed(socRolloverResultInfo.getCourseOfferingsCreated() + " transitioned with " +
552 socRolloverResultInfo.getCourseOfferingsSkipped() + " exception" + plural);
553 }
554 String plural = _createPlural(socRolloverResultInfo.getActivityOfferingsSkipped());
555 form.setActivityOfferingsAllowed(socRolloverResultInfo.getActivityOfferingsCreated() + " transitioned with " +
556 socRolloverResultInfo.getActivityOfferingsSkipped() + " exception" + plural);
557 Date dateCompleted = socRolloverResultInfo.getDateCompleted();
558 String updatedDateStr = helper.formatDateAndTime(dateCompleted);
559
560 String status = _createStatusString(socRolloverResultInfo);
561 if ((CourseOfferingSetServiceConstants.SUBMITTED_RESULT_STATE_KEY.equals(stateKey) ||
562 CourseOfferingSetServiceConstants.RUNNING_RESULT_STATE_KEY.equals(stateKey))) {
563 form.setDateCompleted("Rollover in progress");
564 } else {
565 form.setDateCompleted(updatedDateStr + status);
566 }
567
568 String rolloverDuration = _computeRolloverDuration(dateInitiated, dateCompleted);
569 form.setRolloverDuration(rolloverDuration + status);
570 }
571
572 private void _displayRolloverItems(CourseOfferingRolloverManagementForm form,
573 List<SocRolloverResultItemInfo> socRolloverResultItemInfos,
574 List<SocRolloverResultItemInfo> socRolloverResultItemInfosCopy)
575 throws InvalidParameterException, MissingParameterException, DoesNotExistException, PermissionDeniedException,
576 OperationFailedException {
577
578 form.getSocRolloverResultItems().clear();
579
580 for (SocRolloverResultItemInfo socRolloverResultItemInfo : socRolloverResultItemInfosCopy) {
581 if (CourseOfferingSetServiceConstants.SUCCESSFUL_RESULT_ITEM_STATES.contains(socRolloverResultItemInfo.getStateKey())) {
582 socRolloverResultItemInfos.remove(socRolloverResultItemInfo);
583 } else {
584 String courseOfferingId = socRolloverResultItemInfo.getTargetCourseOfferingId();
585 if (courseOfferingId == null || courseOfferingId.isEmpty()) {
586 courseOfferingId = socRolloverResultItemInfo.getSourceCourseOfferingId();
587 }
588
589 CourseOfferingInfo courseOfferingInfo = _getCourseOfferingService().getCourseOffering(courseOfferingId, new ContextInfo());
590 SocRolloverResultItemWrapper socRolloverResultItemWrapper = new SocRolloverResultItemWrapper();
591 socRolloverResultItemWrapper.setCourse(courseOfferingInfo.getCourseOfferingCode());
592 if (socRolloverResultItemInfo.getMessage() != null) {
593 socRolloverResultItemWrapper.setMessage(socRolloverResultItemInfo.getMessage().getPlain());
594 }
595 socRolloverResultItemWrapper.setState(socRolloverResultItemInfo.getStateKey());
596
597 try {
598 StateInfo stateInfo = this._getStateService().getState(socRolloverResultItemInfo.getStateKey(), ContextUtils.getContextInfo());
599 if (stateInfo != null) {
600 socRolloverResultItemWrapper.setStateName((stateInfo.getName() != null) ? stateInfo.getName() : socRolloverResultItemInfo.getStateKey());
601 }
602 } catch (DoesNotExistException ex) {
603 socRolloverResultItemWrapper.setStateName(socRolloverResultItemInfo.getStateKey());
604 }
605 form.getSocRolloverResultItems().add(socRolloverResultItemWrapper);
606 }
607 }
608 }
609
610
611 @RequestMapping(params = "methodToCall=showRolloverResults")
612 public ModelAndView showRolloverResults(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
613 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
614
615 CourseOfferingViewHelperService helper = getViewHelperService(form);
616
617 String targetTermCode = form.getRolloverTargetTermCode();
618 List<TermInfo> termList = helper.findTermByTermCode(targetTermCode);
619 if (termList.isEmpty()) {
620 GlobalVariables.getMessageMap().putError("rolloverTargetTermCode", "error.rollover.targetTerm.noResults", targetTermCode);
621 form.resetForm();
622 return getUIFModelAndView(form);
623 } else {
624 int firstValue = 0;
625 TermInfo targetTerm = termList.get(firstValue);
626 form.setTargetTerm(targetTerm);
627 form.setTargetTermCode(targetTermCode);
628 String targetTermId = targetTerm.getId();
629
630 List<SocRolloverResultInfo> socRolloverResultInfos = helper.findRolloverByTerm(targetTermId);
631 if (socRolloverResultInfos == null || socRolloverResultInfos.isEmpty()) {
632 GlobalVariables.getMessageMap().putError("rolloverTargetTermCode", "error.rollover.targetTerm.noResults", targetTermCode);
633 form.resetForm();
634 return getUIFModelAndView(form);
635 } else {
636 if (socRolloverResultInfos.size() > 1) {
637 LOGGER.warn("Multiple Soc Rollover Results Found");
638 }
639 _disableReleaseToDeptsIfNeeded(helper, targetTermId, form);
640 SocRolloverResultInfo socRolloverResultInfo = socRolloverResultInfos.get(firstValue);
641 String stateKey = socRolloverResultInfo.getStateKey();
642 _setStatus(stateKey, form);
643
644 SocInfo socInfo = _getSocService().getSoc(socRolloverResultInfo.getSourceSocId(), new ContextInfo());
645
646 _displayRolloverInfo(socInfo, socRolloverResultInfo, form, helper, stateKey, targetTermId);
647
648
649 try {
650 List<SocRolloverResultItemInfo> socRolloverResultItemInfos =
651 _getSocService().getSocRolloverResultItemsByResultId(socRolloverResultInfo.getId(), new ContextInfo());
652 List<SocRolloverResultItemInfo> socRolloverResultItemInfosCopy =
653 new CopyOnWriteArrayList<SocRolloverResultItemInfo>(socRolloverResultItemInfos);
654
655 _displayRolloverItems(form, socRolloverResultItemInfos, socRolloverResultItemInfosCopy);
656 } catch (UnhandledException ue) {
657 throw new RuntimeException(ue);
658 } catch (DoesNotExistException dne) {
659 throw new RuntimeException(dne);
660 }
661 }
662 }
663 return getUIFModelAndView(form, ROLLOVER_DETAILS_PAGEID);
664 }
665
666
667
668
669 public CourseOfferingRolloverManagementForm releaseToDepts(CourseOfferingRolloverManagementForm form, BindingResult result,
670 HttpServletRequest request, HttpServletResponse response) throws Exception {
671 LOGGER.info("releaseToDepts");
672 CourseOfferingViewHelperService helper = getViewHelperService(form);
673 TermInfo targetTerm = form.getTargetTerm();
674 if (targetTerm == null) {
675
676 GlobalVariables.getMessageMap().putError("approveCheckbox", "error.rollover.invalidTerm");
677 } else {
678
679 LOGGER.info("Ready to release to depts");
680 SocInfo socInfo = helper.getMainSoc(targetTerm.getId());
681 if (!socInfo.getStateKey().equals(CourseOfferingSetServiceConstants.DRAFT_SOC_STATE_KEY)) {
682
683 form.setSocReleasedToDepts(true);
684 } else {
685
686 _getSocService().changeSocState(socInfo.getId(), CourseOfferingSetServiceConstants.OPEN_SOC_STATE_KEY, new ContextInfo());
687 form.setSocReleasedToDepts(true);
688 }
689
690 showRolloverResults(form, result, request, response);
691 KSUifUtils.addGrowlMessageIcon(GrowlIcon.SUCCESS, CourseOfferingConstants.COURSEOFFERING_ROLLOVER_RELEASE_TO_DEPTS_SUCCESSFULLY);
692 }
693 return form;
694 }
695
696 @RequestMapping(params = "methodToCall=checkApproval")
697 public ModelAndView checkApproval(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
698 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
699 LOGGER.info("checkApproval " + form.getAcceptIndicator());
700 return getUIFModelAndView(form);
701 }
702
703 @RequestMapping(params = "methodToCall=redoRollover")
704 public ModelAndView redoRollover(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
705 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
706 LOGGER.info("redoRollover ");
707 return getUIFModelAndView(form);
708 }
709
710 @RequestMapping(params = "methodToCall=confirmReleaseToDepts")
711 public ModelAndView confirmReleaseToDepts(@ModelAttribute("KualiForm") CourseOfferingRolloverManagementForm form, @SuppressWarnings("unused") BindingResult result,
712 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
713 LOGGER.info("confirmReleaseToDepts ");
714 if(form.getActionParamaterValue("confirm") == null || form.getActionParamaterValue("confirm").equals("")){
715
716 return showDialog("releaseToDepts", form, request, response);
717 } else if (form.getActionParamaterValue("confirm").equals("do") ){
718 form = releaseToDepts(form, result, request, response);
719 form.getDialogManager().removeAllDialogs();
720 form.setLightboxScript("closeLightbox('releaseToDepts');");
721 }
722 return getUIFModelAndView(form);
723 }
724
725 private String getTermDisplayString(String termId, TermInfo term) {
726
727 StringBuilder stringBuilder = new StringBuilder();
728 Formatter formatter = new Formatter(stringBuilder, Locale.US);
729 String displayString = termId;
730 if (term != null) {
731 String startDate = DateFormatters.MONTH_DAY_YEAR_DATE_FORMATTER.format(term.getStartDate());
732 String endDate = DateFormatters.MONTH_DAY_YEAR_DATE_FORMATTER.format(term.getEndDate());
733 String termType = term.getName();
734 formatter.format("%s (%s to %s)", termType, startDate, endDate);
735 displayString = stringBuilder.toString();
736 }
737 return displayString;
738 }
739
740 private CourseOfferingSetService _getSocService() {
741 if (socService == null) {
742 socService = (CourseOfferingSetService) GlobalResourceLoader.getService(new QName(CourseOfferingSetServiceConstants.NAMESPACE,
743 CourseOfferingSetServiceConstants.SERVICE_NAME_LOCAL_PART));
744 }
745 return socService;
746 }
747
748 private CourseOfferingService _getCourseOfferingService() {
749 if (coService == null) {
750 coService = (CourseOfferingService) GlobalResourceLoader.getService(new QName(CourseOfferingServiceConstants.NAMESPACE,
751 CourseOfferingServiceConstants.SERVICE_NAME_LOCAL_PART));
752 }
753 return coService;
754 }
755
756 private StateService _getStateService() {
757 if (stateService == null) {
758 stateService = (StateService) GlobalResourceLoader.getService(new QName(StateServiceConstants.NAMESPACE,
759 StateServiceConstants.SERVICE_NAME_LOCAL_PART));
760 }
761 return stateService;
762 }
763 private AcademicCalendarService _getAcalService() {
764 if (acalService == null) {
765 acalService = (AcademicCalendarService) GlobalResourceLoader.getService(new QName(AcademicCalendarServiceConstants.NAMESPACE,
766 AcademicCalendarServiceConstants.SERVICE_NAME_LOCAL_PART));
767 }
768 return acalService;
769 }
770 }