View Javadoc

1   package org.kuali.student.enrollment.class2.courseoffering.controller;
2   
3   import org.apache.commons.lang.BooleanUtils;
4   import org.apache.commons.lang.StringUtils;
5   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
6   import org.kuali.rice.kim.api.identity.Person;
7   import org.kuali.rice.krad.exception.AuthorizationException;
8   import org.kuali.rice.krad.maintenance.MaintenanceDocument;
9   import org.kuali.rice.krad.uif.UifConstants;
10  import org.kuali.rice.krad.uif.UifParameters;
11  import org.kuali.rice.krad.util.GlobalVariables;
12  import org.kuali.rice.krad.util.KRADConstants;
13  import org.kuali.rice.krad.web.controller.MaintenanceDocumentController;
14  import org.kuali.rice.krad.web.form.DocumentFormBase;
15  import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
16  import org.kuali.rice.krad.web.form.UifFormBase;
17  import org.kuali.student.common.uif.form.KSUifMaintenanceDocumentForm;
18  import org.kuali.student.common.uif.util.KSControllerHelper;
19  import org.kuali.student.enrollment.class2.courseoffering.dto.CourseOfferingContextBar;
20  import org.kuali.student.enrollment.class2.courseoffering.dto.CourseOfferingEditWrapper;
21  import org.kuali.student.enrollment.class2.courseoffering.dto.FormatOfferingWrapper;
22  import org.kuali.student.enrollment.class2.courseoffering.dto.OrganizationInfoWrapper;
23  import org.kuali.student.enrollment.class2.courseoffering.service.impl.CourseOfferingEditMaintainableImpl;
24  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingConstants;
25  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingResourceLoader;
26  import org.kuali.student.enrollment.common.util.EnrollConstants;
27  import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
28  import org.kuali.student.enrollment.courseoffering.dto.CreditOptionInfo;
29  import org.kuali.student.enrollment.courseofferingset.dto.SocInfo;
30  import org.kuali.student.enrollment.courseofferingset.service.CourseOfferingSetService;
31  import org.kuali.student.r2.common.constants.CommonServiceConstants;
32  import org.kuali.student.r2.common.dto.AttributeInfo;
33  import org.kuali.student.r2.common.dto.ContextInfo;
34  import org.kuali.student.r2.common.util.ContextUtils;
35  import org.kuali.student.r2.common.util.constants.CourseOfferingServiceConstants;
36  import org.kuali.student.r2.common.util.constants.CourseOfferingSetServiceConstants;
37  import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
38  import org.kuali.student.r2.common.util.date.DateFormatters;
39  import org.kuali.student.r2.core.acal.dto.TermInfo;
40  import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
41  import org.kuali.student.r2.core.class1.search.CourseOfferingManagementSearchImpl;
42  import org.kuali.student.r2.core.class1.state.service.StateService;
43  import org.kuali.student.r2.core.class1.type.service.TypeService;
44  import org.kuali.student.r2.core.constants.StateServiceConstants;
45  import org.kuali.student.r2.core.constants.TypeServiceConstants;
46  import org.kuali.student.r2.core.organization.dto.OrgInfo;
47  import org.kuali.student.r2.core.organization.service.OrganizationService;
48  import org.kuali.student.r2.lum.course.dto.CourseInfo;
49  import org.kuali.student.r2.lum.course.service.CourseService;
50  import org.kuali.student.r2.lum.course.service.assembler.CourseAssemblerConstants;
51  import org.kuali.student.r2.lum.lrc.dto.ResultValueInfo;
52  import org.kuali.student.r2.lum.lrc.dto.ResultValuesGroupInfo;
53  import org.kuali.student.r2.lum.lrc.service.LRCService;
54  import org.kuali.student.r2.lum.util.constants.LrcServiceConstants;
55  import org.springframework.stereotype.Controller;
56  import org.springframework.validation.BindingResult;
57  import org.springframework.web.bind.annotation.ModelAttribute;
58  import org.springframework.web.bind.annotation.RequestMapping;
59  import org.springframework.web.bind.annotation.RequestMethod;
60  import org.springframework.web.servlet.ModelAndView;
61  
62  import javax.servlet.http.HttpServletRequest;
63  import javax.servlet.http.HttpServletResponse;
64  import javax.xml.namespace.QName;
65  import java.util.ArrayList;
66  import java.util.Arrays;
67  import java.util.Collections;
68  import java.util.HashSet;
69  import java.util.List;
70  import java.util.Properties;
71  import java.util.Set;
72  
73  //@Controller
74  //@RequestMapping(value = "/courseOffering")
75  public class CourseOfferingBaseController extends MaintenanceDocumentController {
76  
77      private transient CourseService courseService;
78      private transient TypeService typeService;
79      private transient LRCService lrcService;
80      private transient CourseOfferingSetService courseOfferingSetService;
81      private transient AcademicCalendarService acalService;
82      private transient StateService stateService;
83      private transient OrganizationService organizationService;
84  
85      @Override
86      protected MaintenanceDocumentForm createInitialForm(HttpServletRequest request) {
87          return new KSUifMaintenanceDocumentForm();
88      }
89  
90      @Override
91      public ModelAndView maintenanceEdit(@ModelAttribute("KualiForm") MaintenanceDocumentForm form, BindingResult result,
92                                          HttpServletRequest request, HttpServletResponse response) throws Exception {
93  
94          setupMaintenance(form, request, KRADConstants.MAINTENANCE_EDIT_ACTION);
95  
96          // check view authorization
97          // TODO: this needs to be invoked for each request
98          if (form.getView() != null) {
99              String methodToCall = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
100             checkViewAuthorization(form, methodToCall);
101             String crossListedAlias = request.getParameter("editCrossListedCoAlias");
102             if(StringUtils.equals(crossListedAlias, "true")) {
103                 Object selectedObject =  form.getDocument().getNewMaintainableObject().getDataObject();
104                 if(selectedObject instanceof CourseOfferingEditWrapper) {
105                     ((CourseOfferingEditWrapper) selectedObject).setEditCrossListedCoAlias(true);
106                 }
107             }
108 //            form.setEditAuthz(checkEditViewAuthz(form));
109         }
110 
111         //populate the previousFormsMap of the form. The map contains info about the previous view to generate customized breadcrumb
112 //        KSUifUtils.populationPreviousFormsMap(request, (KSUifMaintenanceDocumentForm) form);
113 
114         return getUIFModelAndView(form);
115     }
116 
117     @Override
118     @RequestMapping(params = "methodToCall=route")
119     public ModelAndView route(@ModelAttribute("KualiForm") DocumentFormBase form, BindingResult result,
120                               HttpServletRequest request, HttpServletResponse response) {
121 
122         super.route(form, result, request, response);
123 
124         if( GlobalVariables.getMessageMap().hasErrors() ) {
125             return handleRouteForErrors( form );
126         }
127 
128         if( this instanceof CourseOfferingCreateController ) {
129             return handleRouteForCoCreate( form );
130         }
131 
132         return handleRouteForCoEdit(form);
133     }
134 
135     /* Returns a ModelAndView for the route()-method to return to original view if there were errors.
136      * Should only be called if there are indeed errors.
137      */
138     private ModelAndView handleRouteForErrors( DocumentFormBase form ) {
139 
140         assert ( GlobalVariables.getMessageMap().hasErrors() );
141 
142         if (((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject() instanceof CourseOfferingEditWrapper){
143             CourseOfferingEditMaintainableImpl viewHelper = (CourseOfferingEditMaintainableImpl)KSControllerHelper.getViewHelperService(form);
144             //Make the format type drop down readonly.. otherwise, we run into display issue when the server returns back error
145             CourseOfferingEditWrapper dataObject = (CourseOfferingEditWrapper)((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject();
146             viewHelper.populateFormatNames(dataObject);
147         }
148 
149         return getUIFModelAndView(form);    // because there were errors, return a MAV to re-nav back to
150     }
151 
152     /* Returns a ModelAndView for the route()-method to return a new view if we are creating a CO */
153     private ModelAndView handleRouteForCoCreate( DocumentFormBase form ) {
154 
155         assert( this instanceof CourseOfferingCreateController );
156 
157         Properties urlParameters = new Properties();
158 
159         CourseOfferingEditWrapper dataObject = (CourseOfferingEditWrapper)((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject();
160 
161         urlParameters.put(EnrollConstants.GROWL_MESSAGE, CourseOfferingConstants.COURSE_OFFERING_CREATE_SUCCESS);
162         urlParameters.put(EnrollConstants.GROWL_MESSAGE_PARAMS, dataObject.getCourseOfferingCode());
163 
164         urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, "show");
165         urlParameters.put("termCode", dataObject.getTerm().getCode());
166         if (dataObject.getCourseOfferingInfo().getCourseNumberSuffix() != null && !StringUtils.isBlank(dataObject.getCourseOfferingInfo().getCourseNumberSuffix())) {
167             urlParameters.put("inputCode", dataObject.getCourseOfferingInfo().getCourseOfferingCode().concat(dataObject.getCourseOfferingInfo().getCourseNumberSuffix()));
168         } else {
169             urlParameters.put("inputCode", dataObject.getCourseOfferingInfo().getCourseOfferingCode());
170         }
171         urlParameters.put("viewId",CourseOfferingConstants.MANAGE_CO_VIEW_ID);
172         urlParameters.put("pageId",CourseOfferingConstants.MANAGE_THE_CO_PAGE);
173         urlParameters.put("withinPortal","false");
174 
175         return super.performRedirect(form, CourseOfferingConstants.MANAGE_CO_CONTROLLER_PATH, urlParameters);
176     }
177 
178     /* Returns a ModelAndView for the route()-method to return a new view if we are editing a CO */
179     private ModelAndView handleRouteForCoEdit( DocumentFormBase form ) {
180 
181         assert ( !(this instanceof CourseOfferingCreateController) );
182 
183         String urlToRedirectTo = "";
184         Properties urlParameters = new Properties();
185 
186         GlobalVariables.getUifFormManager().removeSessionForm(form);    // clear current form from session
187 
188         // create a Growl-message
189         CourseOfferingEditWrapper dataObject = (CourseOfferingEditWrapper)((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject();
190         urlParameters.put(EnrollConstants.GROWL_MESSAGE, CourseOfferingConstants.COURSE_OFFERING_EDIT_SUCCESS);
191         urlParameters.put(EnrollConstants.GROWL_MESSAGE_PARAMS, dataObject.getCourseOfferingCode());
192 
193         // determine which url to redirect to
194         String returnLocationFromForm = form.getReturnLocation();
195         if( StringUtils.contains( returnLocationFromForm,"viewId=courseOfferingManagementView" )
196                 || StringUtils.contains( returnLocationFromForm,"pageId=manageTheCourseOfferingPage" ) )
197         {
198             if ( !returnLocationFromForm.contains("methodToCall=") ) {
199                 // This happens when we display a list of COs and then user click on Manage action
200                 form.getViewRequestParameters().put(CourseOfferingManagementSearchImpl.SearchParameters.IS_EXACT_MATCH_CO_CODE_SEARCH, Boolean.TRUE.toString());
201             }
202             else {
203                 form.getViewRequestParameters().put(CourseOfferingManagementSearchImpl.SearchParameters.IS_EXACT_MATCH_CO_CODE_SEARCH, Boolean.FALSE.toString());
204                 //urlToRedirectTo = returnLocationFromForm.replaceFirst("methodToCall=[a-zA-Z0-9]+","methodToCall=show");
205             }
206             urlToRedirectTo = returnLocationFromForm.replaceFirst("methodToCall=[a-zA-Z0-9]+","methodToCall=show");
207         }
208         else {
209             urlToRedirectTo = returnLocationFromForm;
210         }
211 
212         // special handling if navigating to a specific CO
213         String loadNewCO = form.getActionParameters().get( "coId" );
214         if( StringUtils.isNotBlank( loadNewCO ) ) {
215 
216             urlParameters.put( KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.Maintenance.METHOD_TO_CALL_EDIT );
217             urlParameters.put( "courseOfferingInfo.id", loadNewCO );
218             urlParameters.put( KRADConstants.DATA_OBJECT_CLASS_ATTRIBUTE, CourseOfferingEditWrapper.class.getName() );
219             urlParameters.put( UifConstants.UrlParams.SHOW_HOME, BooleanUtils.toStringTrueFalse(false) );
220 
221             urlParameters.put( "returnLocation", urlToRedirectTo );
222 
223             urlToRedirectTo = "courseOffering";
224         }
225 
226         return performRedirect(form, urlToRedirectTo, urlParameters);
227     }
228 
229     protected void populateCreateCourseOfferingForm(MaintenanceDocumentForm form, HttpServletRequest request) {
230 
231         try {
232             ContextInfo contextInfo = ContextUtils.createDefaultContextInfo();
233             MaintenanceDocument document = form.getDocument();
234             String termId = request.getParameter(CourseOfferingConstants.TARGET_TERM_ID);
235             CourseInfo courseInfo = getCourseService().getCourse(request.getParameter(CourseOfferingConstants.COURSE_ID), contextInfo);
236 
237             //1. set CourseOfferingInfo - no saved Course Offering as of yet (see logic in CourseOfferingEditMaintainableImpl.retrieveObjectForEditOrCopy
238             CourseOfferingInfo coInfo = createCourseOfferingInfo(termId, courseInfo);
239             CourseOfferingEditWrapper formObject = new CourseOfferingEditWrapper(coInfo);
240             formObject.setCreateCO(true);
241 
242             //2. set CourseInfo
243             formObject.setCourse(courseInfo);
244 
245             //3. set formatOfferingList
246             formObject.setFormatOfferingList(new ArrayList<FormatOfferingWrapper>());
247             FormatOfferingWrapper defaultFO = new FormatOfferingWrapper();
248            // defaultFO.setFormatInfo(courseInfo.getFormats().get(0));
249             defaultFO.setFormatId(courseInfo.getFormats().get(0).getId());
250             defaultFO.getRenderHelper().setNewRow(true);
251             formObject.getFormatOfferingList().add(defaultFO);
252 
253             //4. Checking if Grading Options should be disabled or not and assign default (if no value)
254             //5. Checking if there are any student registration options from CLU for screen display
255             List<String> studentRegOptions = new ArrayList<String>();
256             List<String> crsGradingOptions = new ArrayList<String>();
257             if (courseInfo != null) {
258                 List<String> gradingOptions = courseInfo.getGradingOptions();
259                 Set<String> regOpts = new HashSet<String>(Arrays.asList(CourseOfferingServiceConstants.ALL_STUDENT_REGISTRATION_OPTION_TYPE_KEYS));
260                 for (String gradingOption : gradingOptions) {
261                     if (regOpts.contains(gradingOption)) {
262                         studentRegOptions.add(gradingOption);
263                     } else {
264                         crsGradingOptions.add(gradingOption);
265                     }
266                 }
267                 //Audit is pulled out into a dynamic attribute on course so map it back
268                 if("true".equals(courseInfo.getAttributeValue(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_AUDIT))){
269                     studentRegOptions.add(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT);
270                 }
271             }
272 
273             formObject.setStudentRegOptions(studentRegOptions);
274             formObject.setCrsGradingOptions(crsGradingOptions);
275 
276             //6. Defining Credit Option and if CLU is fixed (then it's disabled)
277             boolean creditOptionFixed = false;
278             CreditOptionInfo creditOption = new CreditOptionInfo();
279 
280             //Grab the Course's credit constraints
281             //FindBugs: getCreditOptions() null check is in CourseInfo
282             List<ResultValuesGroupInfo> courseCreditOptions = courseInfo.getCreditOptions();
283 
284             //Lookup the related course's credit constraints and set them on the creditOption
285             if (!courseCreditOptions.isEmpty()) {
286                 ResultValuesGroupInfo resultValuesGroupInfo = courseCreditOptions.get(0);
287                 //Check for fixed
288                 if (resultValuesGroupInfo.getTypeKey().equalsIgnoreCase(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED)) {
289                     if (!resultValuesGroupInfo.getResultValueKeys().isEmpty()) {
290                         creditOption.setCourseFixedCredits(getLrcService().getResultValue(resultValuesGroupInfo.getResultValueKeys().get(0), contextInfo).getValue());
291                     }
292                     //Set the flag
293                     creditOptionFixed = true;
294 
295                     //Default the value
296                     creditOption.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED);
297                     creditOption.setFixedCredit(creditOption.getCourseFixedCredits());
298                     creditOption.getAllowedCredits().add(creditOption.getCourseFixedCredits());
299                 } else {
300                     //This is either range or multiple
301 
302                     //Copy all the allowed credits and sort so that the multiple checkboxes can be properly displayed
303                     List<ResultValueInfo> resultValueInfos = getLrcService().getResultValuesForResultValuesGroup(resultValuesGroupInfo.getKey(), contextInfo);
304                     for (ResultValueInfo rVI: resultValueInfos) {
305                         creditOption.getAllowedCredits().add(rVI.getValue());
306                     }
307                     Collections.sort(creditOption.getAllowedCredits());
308 
309                     if (resultValuesGroupInfo.getTypeKey().equalsIgnoreCase(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE)) {
310                         creditOption.setCourseMinCredits(resultValuesGroupInfo.getResultValueRange().getMinValue());
311                         creditOption.setCourseMaxCredits(resultValuesGroupInfo.getResultValueRange().getMaxValue());
312 
313                         //Default the value
314                         creditOption.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE);
315                         creditOption.setMinCredits(creditOption.getCourseMinCredits());
316                         creditOption.setMaxCredits(creditOption.getCourseMaxCredits());
317                     } else if (resultValuesGroupInfo.getTypeKey().equalsIgnoreCase(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE)) {
318                         //Default the value
319                         creditOption.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE);
320                         creditOption.getCredits().addAll(creditOption.getAllowedCredits());
321                     }
322                 }
323             }
324 
325             formObject.setCreditOption(creditOption);
326             formObject.setCreditOptionFixed(creditOptionFixed);
327 
328             formObject.setOrganizationNames(new ArrayList<OrganizationInfoWrapper>());
329 
330             ArrayList<OrganizationInfoWrapper> orgList = new ArrayList<OrganizationInfoWrapper>();
331 
332             // ??? Do we have to pull them off courseInfo ?
333             if(courseInfo.getUnitsDeployment() != null){
334                 for(String orgId: courseInfo.getUnitsDeployment()){
335                     OrgInfo orgInfo = getOrganizationService().getOrg(orgId,contextInfo);
336                     orgList.add(new OrganizationInfoWrapper(orgInfo));
337                 }
338             }
339             formObject.setOrganizationNames(orgList);
340 
341             // adding SOC
342             SocInfo socInfo = getCourseOfferingSetService().getSoc(request.getParameter(CourseOfferingConstants.SOC_ID), contextInfo);
343             formObject.setSocInfo(socInfo);
344 
345             setTermPropertiesOnFormObject(formObject, termId, contextInfo );
346             formObject.setContextBar(CourseOfferingContextBar.NEW_INSTANCE(formObject.getTerm(), formObject.getSocInfo(),
347                     getStateService(), getAcalService(), contextInfo) );
348 
349             document.getNewMaintainableObject().setDataObject(formObject);
350             document.getOldMaintainableObject().setDataObject(formObject);
351             document.getDocumentHeader().setDocumentDescription("Create CO - " + courseInfo.getCode());
352 
353             // Authz check
354             Person user = GlobalVariables.getUserSession().getPerson();
355             boolean canOpenView = this.getDocumentDictionaryService().getDocumentAuthorizer(document).canOpen(document,user);
356 
357             // Work around, should be fixed with KULRICE-8049
358             if (!canOpenView) {
359                 throw new AuthorizationException(user.getPrincipalName(), "open", null,
360                         "User '" + user.getPrincipalName() + "' is not authorized to open view", null);
361             }
362         } catch (Exception e) {
363             throw new RuntimeException(e);
364         }
365     }
366 
367     private void setTermPropertiesOnFormObject(CourseOfferingEditWrapper formObject, String termId, ContextInfo contextInfo ) throws Exception {
368 
369         TermInfo termInfo = getAcalService().getTerm(termId, contextInfo);
370         formObject.setTerm(termInfo);
371         formObject.setTermName(termInfo.getName());
372 
373         // Setting term string: Fall 2012 (09/28/2012 to 12/15/2012)
374         String termStartDate = new String( DateFormatters.MONTH_DAY_YEAR_DATE_FORMATTER.format( termInfo.getStartDate() ) );
375         String termEndDate = new String( DateFormatters.MONTH_DAY_YEAR_DATE_FORMATTER.format( termInfo.getEndDate() ) );
376         StringBuilder termStartEnd = new StringBuilder();
377         termStartEnd.append( termInfo.getName() );
378         termStartEnd.append( " (" );
379         termStartEnd.append( termStartDate );
380         termStartEnd.append( " to " );
381         termStartEnd.append( termEndDate );
382         termStartEnd.append( ")" );
383         formObject.setTermStartEnd( termStartEnd.toString() );
384     }
385 
386     protected CourseOfferingInfo createCourseOfferingInfo(String termId, CourseInfo courseInfo) throws Exception {
387 
388         CourseOfferingInfo courseOffering = new CourseOfferingInfo();
389 
390         courseOffering.setTermId(termId);
391         courseOffering.setCourseOfferingTitle(courseInfo.getCourseTitle());
392         courseOffering.setCourseId(courseInfo.getId());
393         courseOffering.setCourseCode(courseInfo.getCode());
394         courseOffering.setTypeKey(LuiServiceConstants.COURSE_OFFERING_TYPE_KEY);
395         courseOffering.setStateKey(LuiServiceConstants.LUI_CO_STATE_DRAFT_KEY);
396         courseOffering.setHasWaitlist(false);
397         courseOffering.setCourseOfferingCode(courseInfo.getCode());
398 
399         //Copy grading and credit options
400         if(!courseInfo.getCreditOptions().isEmpty()){
401             courseOffering.setCreditOptionId(courseInfo.getCreditOptions().get(0).getKey());
402         }
403         //Remove these two special student registration options and set them on the CO
404         List<String> courseGradingOptions = new ArrayList<String>(courseInfo.getGradingOptions());
405         if(courseGradingOptions.remove(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_PASSFAIL) ){
406             courseOffering.getStudentRegistrationGradingOptions().add(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_PASSFAIL);
407         }
408         if(courseGradingOptions.remove(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT) ){
409             courseOffering.getStudentRegistrationGradingOptions().add(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT);
410         }
411         //set the first remaining grading option on the CO
412         if(!courseGradingOptions.isEmpty()){
413             courseOffering.setGradingOptionId(courseGradingOptions.get(0));
414         }
415 
416         // make sure we set attribute information from the course
417         if(!courseInfo.getAttributes().isEmpty()){
418             for(AttributeInfo info: courseInfo.getAttributes()){
419                 // Default the CourseOffering Final Exam Type to the Final Exam type in the Course
420                 if(info.getKey().equals("finalExamStatus")){
421                     courseOffering.setFinalExamType(convertCourseFinalExamTypeToCourseOfferingFinalExamType(info.getValue()));
422                 }
423             }
424         }
425 
426         return courseOffering;
427     }
428 
429     protected static String convertCourseFinalExamTypeToCourseOfferingFinalExamType(String courseFinalExamType){
430         String sRet = null;
431         if("STD".equals(courseFinalExamType))   {
432             sRet = CourseOfferingConstants.COURSEOFFERING_FINAL_EXAM_TYPE_STANDARD;
433         } else if("ALT".equals(courseFinalExamType)) {
434             sRet = CourseOfferingConstants.COURSEOFFERING_FINAL_EXAM_TYPE_ALTERNATE;
435         }
436         return sRet;
437     }
438 
439     @RequestMapping(params = "methodToCall=cancel")
440     @Override
441     public ModelAndView cancel(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
442             HttpServletRequest request, HttpServletResponse response) {
443 
444         DocumentFormBase documentForm = (DocumentFormBase) form;
445         performWorkflowAction(documentForm, UifConstants.WorkflowAction.CANCEL, false);
446 
447         String urlToRedirectTo = "";
448         Properties urlParameters = new Properties();
449 
450         // determine which url to redirect to
451         String returnLocationFromForm = form.getReturnLocation();
452         if( StringUtils.contains( returnLocationFromForm,"viewId=courseOfferingManagementView" )
453                 || StringUtils.contains( returnLocationFromForm,"pageId=manageTheCourseOfferingPage" ) )
454         {
455             if ( !returnLocationFromForm.contains("methodToCall=") ) {  // This happens when we display a list of COs and then user click on Manage action
456                 form.getViewRequestParameters().put(CourseOfferingManagementSearchImpl.SearchParameters.IS_EXACT_MATCH_CO_CODE_SEARCH, Boolean.TRUE.toString());
457             }
458             else {
459                 form.getViewRequestParameters().put(CourseOfferingManagementSearchImpl.SearchParameters.IS_EXACT_MATCH_CO_CODE_SEARCH, Boolean.FALSE.toString());
460             }
461             urlToRedirectTo = returnLocationFromForm.replaceFirst("methodToCall=[a-zA-Z0-9]+","methodToCall=show");
462         }
463         else {
464             urlToRedirectTo = returnLocationFromForm;
465         }
466 
467         String loadNewCO = form.getActionParameters().get( "coId" );
468         if( StringUtils.isNotBlank( loadNewCO ) ) {
469 
470             urlParameters.put( KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.Maintenance.METHOD_TO_CALL_EDIT );
471             urlParameters.put( "courseOfferingInfo.id", loadNewCO );
472             urlParameters.put( KRADConstants.DATA_OBJECT_CLASS_ATTRIBUTE, CourseOfferingEditWrapper.class.getName() );
473             urlParameters.put( UifConstants.UrlParams.SHOW_HOME, BooleanUtils.toStringTrueFalse(false) );
474 
475             urlParameters.put( "returnLocation", urlToRedirectTo );
476 
477             urlToRedirectTo = "courseOffering";
478             GlobalVariables.getUifFormManager().removeSessionForm(form);
479             return performRedirect(form, urlToRedirectTo, urlParameters);
480         }
481 
482         form.setReturnLocation( urlToRedirectTo );
483         return back(form,result,request,response);
484     }
485 
486 
487     /**
488      * This override is specifically for making sure users selected the format types before adding new lines (there is no
489      * util method available at view helper).
490      *
491      * @param form
492      * @return
493      */
494     @RequestMapping(method = RequestMethod.POST, params = "methodToCall=addBlankLine")
495     public ModelAndView addBlankLine(@ModelAttribute("KualiForm") UifFormBase form) {
496 
497         boolean validAction = true;
498         if (((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject() instanceof CourseOfferingEditWrapper){
499             CourseOfferingEditWrapper dataObject = (CourseOfferingEditWrapper)((MaintenanceDocumentForm)form).getDocument().getNewMaintainableObject().getDataObject();
500             String selectedCollectionPath = form.getActionParamaterValue(UifParameters.SELLECTED_COLLECTION_PATH);
501             if (StringUtils.endsWith(selectedCollectionPath, "formatOfferingList")) {
502                 for (FormatOfferingWrapper foWrapper : dataObject.getFormatOfferingList()){
503                     if (StringUtils.isBlank(foWrapper.getFormatOfferingInfo().getFormatId())){
504                         GlobalVariables.getMessageMap().putError("KS-CourseOfferingEdit-DeliveryFormats",CourseOfferingConstants.COURSEOFFERING_FORMAT_REQUIRED);
505                         validAction = false;
506                         break;
507                     }
508                 }
509             }
510         }
511 
512         if (validAction){
513             return super.addBlankLine(form);
514         } else {
515             return getUIFModelAndView(form);
516         }
517 
518     }
519 
520 
521     protected CourseService getCourseService() {
522         if(courseService == null) {
523             courseService = CourseOfferingResourceLoader.loadCourseService();
524         }
525         return this.courseService;
526     }
527 
528     protected LRCService getLrcService() {
529         if(lrcService == null) {
530             lrcService = (LRCService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/lrc", "LrcService"));
531         }
532         return this.lrcService;
533     }
534 
535     protected CourseOfferingSetService getCourseOfferingSetService(){
536         if (courseOfferingSetService == null){
537             courseOfferingSetService = (CourseOfferingSetService) GlobalResourceLoader.getService(new QName(CourseOfferingSetServiceConstants.NAMESPACE, CourseOfferingSetServiceConstants.SERVICE_NAME_LOCAL_PART));
538         }
539         return courseOfferingSetService;
540     }
541 
542     protected AcademicCalendarService getAcalService() {
543         if(acalService == null) {
544             acalService = (AcademicCalendarService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/acal", "AcademicCalendarService"));
545         }
546         return this.acalService;
547     }
548 
549     protected StateService getStateService() {
550         if( stateService == null ) {
551             stateService = (StateService) GlobalResourceLoader.getService( new QName(StateServiceConstants.NAMESPACE, StateServiceConstants.SERVICE_NAME_LOCAL_PART) );
552         }
553         return stateService;
554     }
555 
556     private OrganizationService getOrganizationService(){
557         if(organizationService == null) {
558             organizationService = (OrganizationService) GlobalResourceLoader.getService(new QName(CommonServiceConstants.REF_OBJECT_URI_GLOBAL_PREFIX + "organization", "OrganizationService"));
559         }
560         return organizationService;
561     }
562 
563     protected TypeService getTypeService() {
564         if(typeService == null) {
565             typeService = (TypeService) GlobalResourceLoader.getService(new QName(TypeServiceConstants.NAMESPACE, TypeServiceConstants.SERVICE_NAME_LOCAL_PART));
566         }
567         return this.typeService;
568     }
569 }