View Javadoc
1   /*
2    * Copyright 2014 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  package org.kuali.student.ap.coursesearch.controller;
16  
17  import org.kuali.rice.krad.web.controller.MethodAccessible;
18  import org.kuali.rice.krad.web.controller.extension.KsapControllerBase;
19  import org.kuali.rice.krad.web.form.UifFormBase;
20  import org.kuali.student.ap.academicplan.constants.AcademicPlanServiceConstants;
21  import org.kuali.student.ap.academicplan.dto.TypedObjectReferenceInfo;
22  import org.kuali.student.ap.academicplan.infc.LearningPlan;
23  import org.kuali.student.ap.academicplan.infc.PlanItem;
24  import org.kuali.student.ap.academicplan.infc.TypedObjectReference;
25  import org.kuali.student.ap.coursesearch.dataobject.ActivityOfferingDetailsWrapper;
26  import org.kuali.student.ap.coursesearch.form.CourseSectionDetailsDialogForm;
27  import org.kuali.student.ap.coursesearch.form.CourseSectionDetailsForm;
28  import org.kuali.student.ap.coursesearch.service.CourseDetailsViewHelperService;
29  import org.kuali.student.ap.framework.config.KsapFrameworkServiceLocator;
30  import org.kuali.student.ap.framework.context.PlanConstants;
31  import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
32  import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
33  import org.kuali.student.enrollment.courseoffering.dto.FormatOfferingInfo;
34  import org.kuali.student.enrollment.courseoffering.dto.RegistrationGroupInfo;
35  import org.kuali.student.enrollment.courseoffering.infc.CourseOffering;
36  import org.kuali.student.r2.common.dto.AttributeInfo;
37  import org.kuali.student.r2.common.exceptions.AlreadyExistsException;
38  import org.kuali.student.r2.common.exceptions.DoesNotExistException;
39  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
40  import org.kuali.student.r2.common.exceptions.MissingParameterException;
41  import org.kuali.student.r2.common.exceptions.OperationFailedException;
42  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
43  import org.kuali.student.r2.core.acal.dto.TermInfo;
44  import org.kuali.student.r2.core.acal.infc.Term;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  import org.springframework.stereotype.Controller;
48  import org.springframework.web.bind.annotation.ModelAttribute;
49  import org.springframework.web.bind.annotation.RequestMapping;
50  import org.springframework.web.bind.annotation.RequestParam;
51  import org.springframework.web.servlet.ModelAndView;
52  
53  import javax.json.Json;
54  import javax.json.JsonObjectBuilder;
55  import javax.servlet.ServletException;
56  import javax.servlet.http.HttpServletRequest;
57  import javax.servlet.http.HttpServletResponse;
58  import java.io.IOException;
59  import java.math.BigDecimal;
60  import java.util.ArrayList;
61  import java.util.Collections;
62  import java.util.Comparator;
63  import java.util.HashMap;
64  import java.util.List;
65  import java.util.Map;
66  
67  /**
68   * Controller handling the interactions of the course section portion of the Course Details Page.
69   */
70  @Controller
71  @RequestMapping(value = "/course/details/**")
72  public class CourseSectionDetailsController extends KsapControllerBase {
73      private static final Logger LOG = LoggerFactory.getLogger(CourseSectionDetailsController.class);
74  
75      private static final String COURSE_SECTION_DETAILS_FORM = "CourseDetails-FormView";
76      private static final String COURSE_SECTION_DETAILS_DIALOG = "KSAP-CourseSectionDetailsDialog-FormView";
77      private static final String COURSE_SECTION_DETAILS_ADD_DIALOG = "KSAP-CourseDetailsSection-AddCoursePage";
78      private static final String COURSE_SECTION_DETAILS_REQUISITES_DIALOG = "KSAP-CourseDetailsSection-Requisites";
79  
80      private CourseDetailsViewHelperService viewHelper;
81  
82      /**
83       * @see org.kuali.rice.krad.web.controller.UifControllerBase
84       */
85      @Override
86      protected UifFormBase createInitialForm(HttpServletRequest httpServletRequest) {
87          return new CourseSectionDetailsForm();
88      }
89  
90      /**
91       * Handles the initial loading of the page content for the course section details
92       */
93      @MethodAccessible
94      @RequestMapping(params = "methodToCall=startCourseSectionDetails")
95      public ModelAndView startCourseSectionDetails(@RequestParam(value = "courseId") String courseId,
96                                                    @ModelAttribute("KualiForm") CourseSectionDetailsForm form,
97                                                    HttpServletRequest request,
98                                                    HttpServletResponse response)  {
99          super.start(form, request, response);
100 
101         form.setViewId(COURSE_SECTION_DETAILS_FORM);
102         form.setView(super.getViewService().getViewById(COURSE_SECTION_DETAILS_FORM));
103 
104         getViewHelperService(form).loadCourseSectionDetails(form, courseId);
105 
106         return getUIFModelAndView(form);
107     }
108 
109     /**
110      * Handles the addition of a registration group to the plan.
111      * Requires the regGroupId to be set in the form
112      * Returns null for the method but writes json objects for the page to use in dynamic updating
113      */
114     @MethodAccessible
115     @RequestMapping(params = "methodToCall=addRegGroup")
116     public ModelAndView addRegGroup(@ModelAttribute("KualiForm") CourseSectionDetailsForm form,
117                                                   HttpServletRequest request,
118                                                   HttpServletResponse response) throws IOException, ServletException {
119 
120         JsonObjectBuilder eventList = Json.createObjectBuilder();
121 
122         // Gather information about the registration group
123         String regGroupId = request.getParameter("regGroupId");
124         RegistrationGroupInfo regGroup = null;
125         CourseOffering course = null;
126         List<ActivityOfferingInfo> activities = null;
127         try {
128             regGroup = KsapFrameworkServiceLocator.getCourseOfferingService().getRegistrationGroup(regGroupId, KsapFrameworkServiceLocator.getContext().getContextInfo());
129             course = KsapFrameworkServiceLocator.getCourseOfferingService().getCourseOffering(regGroup.getCourseOfferingId(), KsapFrameworkServiceLocator.getContext().getContextInfo());
130             activities = KsapFrameworkServiceLocator.getCourseOfferingService().getActivityOfferingsByIds(regGroup.getActivityOfferingIds(), KsapFrameworkServiceLocator.getContext().getContextInfo());
131         } catch (DoesNotExistException e) {
132             throw new IllegalArgumentException("CO Service lookup error", e);
133         } catch (InvalidParameterException e) {
134             throw new IllegalArgumentException("CO Service lookup error", e);
135         } catch (MissingParameterException e) {
136             throw new IllegalArgumentException("CO Service lookup error", e);
137         } catch (OperationFailedException e) {
138             throw new IllegalArgumentException("CO Service lookup error", e);
139         } catch (PermissionDeniedException e) {
140             throw new IllegalArgumentException("CO Service lookup error", e);
141         }
142         boolean isVariableCreditCourse = getViewHelperService(form).isVariableCreditCourse(new CourseOfferingInfo(course));
143         List<ActivityOfferingDetailsWrapper> activityWrappers = new ArrayList<ActivityOfferingDetailsWrapper>();
144         Map<String, FormatOfferingInfo> formatOfferingInfoMap = new HashMap<String, FormatOfferingInfo>();
145         for(ActivityOfferingInfo activityOfferingInfo : activities){
146             ActivityOfferingDetailsWrapper activityOfferingDetailsWrapper = getViewHelperService(form).convertAOInfoToWrapper(activityOfferingInfo, isVariableCreditCourse, formatOfferingInfoMap);
147             if (activityOfferingDetailsWrapper.getRegGroupCode() == null || "".equals(activityOfferingDetailsWrapper.getRegGroupCode())) {
148                 activityOfferingDetailsWrapper.setRegGroupCode(regGroup.getRegistrationCode());
149                 activityOfferingDetailsWrapper.setRegGroupId(regGroupId);
150                 activityOfferingDetailsWrapper.setPartOfRegGroup(true);
151             }
152             activityWrappers.add(activityOfferingDetailsWrapper);
153         }
154 
155         // Order Planned Activities
156         String formatOrder = request.getParameter("formatOrder");
157         if(formatOrder!=null){
158             String formatOrderArray[] = formatOrder.split("->");
159             Map<String,Integer> formatOrderMap = new HashMap<String,Integer>();
160             int count = 0;
161             for(String temp : formatOrderArray){
162                 formatOrderMap.put(temp,count);
163                 count++;
164             }
165             for(ActivityOfferingDetailsWrapper temp : activityWrappers){
166                 temp.setFormatIndex(formatOrderMap.get(temp.getActivityFormatName()));
167             }
168             Collections.sort(activityWrappers, new Comparator<ActivityOfferingDetailsWrapper>() {
169                 @Override
170                 public int compare(ActivityOfferingDetailsWrapper a1, ActivityOfferingDetailsWrapper a2) {
171                     if (a1.getFormatIndex() == a2.getFormatIndex()) return 0;
172                     if (a1.getFormatIndex() > a2.getFormatIndex()) return 1;
173                     return -1;
174                 }
175             });
176         }
177 
178 
179         Term term = KsapFrameworkServiceLocator.getTermHelper().getTerm(regGroup.getTermId());
180         LearningPlan learningPlan = KsapFrameworkServiceLocator.getPlanHelper().getDefaultLearningPlan();
181 
182         PlanItem coursePlanItem = null;
183         coursePlanItem = KsapFrameworkServiceLocator.getPlanHelper().findCourseItem(course.getCourseId(),
184                 term.getId(), learningPlan.getId());
185 
186         // Create the new plan item
187         TypedObjectReference planItemRef = new TypedObjectReferenceInfo(PlanConstants.REG_GROUP_TYPE,regGroup.getId());
188 
189 
190         // Set the credits if it came through the request
191         BigDecimal creditValue = null;
192         if (isVariableCreditCourse) {
193             String credits = request.getParameter("credits");
194             if (credits != null) {
195                 creditValue = new BigDecimal(credits);
196             }
197         }
198         List<String> terms = new ArrayList<String>();
199         terms.add(regGroup.getTermId());
200 
201         // Create attribute list
202         List<AttributeInfo> attributes = new ArrayList<AttributeInfo>();
203         AttributeInfo rg2CourseLink = new AttributeInfo(AcademicPlanServiceConstants.PLAN_ITEM_RELATION_TYPE_RG2COURSE,coursePlanItem.getId());
204         attributes.add(rg2CourseLink);
205 
206         // Save the new plan item to the database
207         try{
208             KsapFrameworkServiceLocator.getPlanHelper().addPlanItem(learningPlan.getId(),
209                     coursePlanItem.getCategory(), "", creditValue, terms, planItemRef, attributes);
210         }catch (AlreadyExistsException e){
211             getViewHelperService(form).sendJsonEvents(false,"Course " +course.getCourseCode() + " is already planned for " + term.getName(), response, eventList);
212             return null;
213         }
214 
215         // Get new list of valid registration groups with added plan item
216         List<String> validRegGroups = getViewHelperService(form).getValidRegGroupIds(course.getId(), new HashMap<Object, Object>());
217         List<String> validRegGroupsToRemain = getViewHelperService(form).getValidRegGroupIdsToRemain(course.getId(), new HashMap<Object, Object>());
218 
219         // Create events needed to update the page
220         eventList = getViewHelperService(form).createAddSectionEvent(course.getTermId(), course.getCourseOfferingCode(),regGroup.getCourseOfferingId(),regGroup.getFormatOfferingId(), activityWrappers, eventList);
221         eventList = getViewHelperService(form).createFilterValidRegGroupsEvent(course.getTermId(), course.getCourseOfferingCode(), regGroup.getFormatOfferingId(), validRegGroups, eventList,
222                 new HashMap<Object, Object>());
223         eventList = getViewHelperService(form).createFilterValidRegGroupsForRemovalEvent(course.getTermId(), course.getCourseOfferingCode(), regGroup.getFormatOfferingId(), validRegGroupsToRemain, eventList);
224         List<PlanItem> planItems = KsapFrameworkServiceLocator.getPlanHelper().loadStudentsPlanItemsForCourse(coursePlanItem.getRefObjectId());
225         eventList = getViewHelperService(form).makeUpdatePlanItemStatusMessage(planItems, eventList);
226         getViewHelperService(form).sendJsonEvents(true,"Registration Group For " +course.getCourseOfferingCode() + " added for " + term.getName(), response, eventList);
227         return null;
228     }
229 
230     /**
231      * Handles the filtering of activities when one is selected on the page
232      * Requires the activity id of the one selected
233      * Requires the list of activity ids of all activities that are checked.
234      * Returns null for the method but writes json objects for the page to use in dynamic updating
235      */
236     @MethodAccessible
237     @RequestMapping(params = "methodToCall=filterAOs")
238     public ModelAndView filterAOs(@ModelAttribute("KualiForm") CourseSectionDetailsForm form,
239                                     HttpServletRequest request,
240                                     HttpServletResponse response) throws IOException, ServletException {
241         JsonObjectBuilder eventList = Json.createObjectBuilder();
242         List<String> selectedActivities = new ArrayList<String>();
243         Map<Object, Object> additionalRestrictions = new HashMap<Object, Object>();
244 
245         // Retrieve data from page
246         String selectedActivityId = request.getParameter("selectedActivityId");
247         String checkedActivitiesStr = request.getParameter("checkedActivities");
248         if(!checkedActivitiesStr.isEmpty()){
249             String checkedActivities[] = checkedActivitiesStr.split(",");
250             for(String str : checkedActivities){
251                 selectedActivities.add(str);
252             }
253         }
254 
255         // Add selected activity list to restrictions map
256         additionalRestrictions.put("selectedActivities", selectedActivities);
257 
258         // Retrieve activity offering for the one being interacted with.
259         ActivityOfferingInfo activityOfferingInfo = null;
260         try {
261             activityOfferingInfo = KsapFrameworkServiceLocator.getCourseOfferingService()
262                     .getActivityOffering(selectedActivityId,KsapFrameworkServiceLocator.getContext().getContextInfo());
263         } catch (DoesNotExistException e) {
264             throw new IllegalArgumentException("CO Service lookup error", e);
265         } catch (InvalidParameterException e) {
266             throw new IllegalArgumentException("CO Service lookup error", e);
267         } catch (MissingParameterException e) {
268             throw new IllegalArgumentException("CO Service lookup error", e);
269         } catch (OperationFailedException e) {
270             throw new IllegalArgumentException("CO Service lookup error", e);
271         } catch (PermissionDeniedException e) {
272             throw new IllegalArgumentException("CO Service lookup error", e);
273         }
274 
275         // Retrieve filtered registration groups
276         List<String> regGroups = getViewHelperService(form)
277                 .getValidRegGroupIds(activityOfferingInfo.getCourseOfferingId(), additionalRestrictions);
278 
279         //Create events needed to update the page
280         eventList = getViewHelperService(form).createFilterValidRegGroupsEvent(activityOfferingInfo.getTermId(),
281                 activityOfferingInfo.getCourseOfferingCode(),activityOfferingInfo.getFormatOfferingId(), regGroups, eventList,
282                 additionalRestrictions);
283         getViewHelperService(form).sendJsonEvents(true,"Filtered Activities for those only those in groups with " +
284                 activityOfferingInfo.getCourseOfferingCode() + " - " + activityOfferingInfo.getActivityCode(),
285                 response, eventList);
286 
287         return null;
288     }
289 
290     /**
291      * Handles the creation of a dialog form for adding a Registration Group to the Planner
292      */
293     @MethodAccessible
294     @RequestMapping(params = "methodToCall=startAddDialog")
295     public ModelAndView startAddDialog(@ModelAttribute("KualiForm") UifFormBase form,
296                                                 HttpServletRequest request,
297                                                 HttpServletResponse response)  {
298         // Dialog uses separate form from normal
299         CourseSectionDetailsDialogForm dialogForm = new CourseSectionDetailsDialogForm();
300         super.start(dialogForm, request, response);
301 
302         // Fill in basic view information to new form
303         dialogForm.setViewId(COURSE_SECTION_DETAILS_DIALOG);
304         dialogForm.setPageId(COURSE_SECTION_DETAILS_ADD_DIALOG);
305         dialogForm.setView(super.getViewService().getViewById(COURSE_SECTION_DETAILS_DIALOG));
306 
307         // Copy information from original view
308         dialogForm.setFormPostUrl(form.getFormPostUrl());
309         dialogForm.setRequestUrl(form.getRequestUrl());
310 
311         // Fill in addition information needed by the add dialog
312         String regGroupId = request.getParameter("regGroupId");
313         String formatOrder = request.getParameter("formatOrder");
314 
315         boolean variableCredit = Boolean.parseBoolean(request.getParameter("variableCredit"));
316 
317         dialogForm.setRegGroupId(regGroupId);
318         dialogForm.setFormatOrder(formatOrder);
319 
320         RegistrationGroupInfo regGroup = null;
321         CourseOffering course = null;
322         TermInfo term = null;
323 
324         try {
325             regGroup = KsapFrameworkServiceLocator.getCourseOfferingService().getRegistrationGroup(regGroupId, KsapFrameworkServiceLocator.getContext().getContextInfo());
326             course = KsapFrameworkServiceLocator.getCourseOfferingService().getCourseOffering(regGroup.getCourseOfferingId(), KsapFrameworkServiceLocator.getContext().getContextInfo());
327             term = KsapFrameworkServiceLocator.getAcademicCalendarService().getTerm(course.getTermId(), KsapFrameworkServiceLocator.getContext().getContextInfo());
328         } catch (DoesNotExistException e) {
329             throw new IllegalArgumentException("CO Service lookup error", e);
330         } catch (InvalidParameterException e) {
331             throw new IllegalArgumentException("CO Service lookup error", e);
332         } catch (MissingParameterException e) {
333             throw new IllegalArgumentException("CO Service lookup error", e);
334         } catch (OperationFailedException e) {
335             throw new IllegalArgumentException("CO Service lookup error", e);
336         } catch (PermissionDeniedException e) {
337             throw new IllegalArgumentException("CO Service lookup error", e);
338         }
339 
340         dialogForm.setRegGroupCode(regGroup.getRegistrationCode());
341         dialogForm.setCourseOfferingCode(course.getCourseOfferingCode());
342         dialogForm.setVariableCredit(variableCredit);
343         dialogForm.setCourseOfferingTitle(course.getCourseOfferingTitle());
344         dialogForm.setTermId(course.getTermId());
345         dialogForm.setTermName(term.getName());
346         dialogForm.setCourseOffering(course);
347         dialogForm.setCreditsDisplay(course.getCreditCnt());
348 
349 
350 
351         return getUIFModelAndView(dialogForm);
352     }
353 
354     /**
355      * Handles the creation of a dialog form for adding a Registration Group to the Planner
356      */
357     @MethodAccessible
358     @RequestMapping(params = "methodToCall=startRequisitesDialog")
359     public ModelAndView startRequisitesDialog(@ModelAttribute("KualiForm") UifFormBase form,
360                                        HttpServletRequest request,
361                                        HttpServletResponse response)  {
362         // Dialog uses separate form from normal
363         CourseSectionDetailsDialogForm dialogForm = new CourseSectionDetailsDialogForm();
364         super.start(dialogForm, request, response);
365 
366         // Fill in basic view information to new form
367         dialogForm.setViewId(COURSE_SECTION_DETAILS_DIALOG);
368         dialogForm.setPageId(COURSE_SECTION_DETAILS_REQUISITES_DIALOG);
369         dialogForm.setView(super.getViewService().getViewById(COURSE_SECTION_DETAILS_DIALOG));
370 
371         // Copy information from original view
372         dialogForm.setFormPostUrl(form.getFormPostUrl());
373         dialogForm.setRequestUrl(form.getRequestUrl());
374 
375         dialogForm = getViewHelperService(dialogForm)
376                 .setupActivityRequisitesDialog(request.getParameter("activityOfferingId"),dialogForm);
377 
378         return getUIFModelAndView(dialogForm);
379     }
380 
381     /**
382      * Retrieve the view helper from a form.
383      *
384      * @param form - Form helper is being retrieved for
385      * @return Form's view helper
386      */
387     private CourseDetailsViewHelperService getViewHelperService(UifFormBase form) {
388         if(viewHelper==null){
389             if(form.getViewHelperService()==null){
390                 form.setViewId(COURSE_SECTION_DETAILS_FORM);
391                 form.setView(super.getViewService().getViewById(COURSE_SECTION_DETAILS_FORM));
392             }
393             viewHelper = (CourseDetailsViewHelperService) form.getViewHelperService();
394         }
395         return viewHelper;
396     }
397 }