View Javadoc

1   /**
2    * Copyright 2012 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   */
16  package org.kuali.student.enrollment.class2.courseoffering.controller;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.kuali.rice.core.api.criteria.PredicateFactory;
21  import org.kuali.rice.core.api.criteria.QueryByCriteria;
22  import org.kuali.rice.krad.web.controller.UifControllerBase;
23  import org.kuali.rice.krad.web.form.UifFormBase;
24  import org.kuali.student.r2.core.acal.dto.TermInfo;
25  import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
26  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingResourceLoader;
27  import org.kuali.student.enrollment.courseoffering.dto.*;
28  import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
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.dto.ContextInfo;
32  import org.kuali.student.r2.common.util.ContextUtils;
33  import org.kuali.student.r2.core.class1.state.dto.StateInfo;
34  import org.kuali.student.r2.core.class1.state.service.StateService;
35  import org.kuali.student.r2.core.scheduling.service.SchedulingService;
36  import org.springframework.stereotype.Controller;
37  import org.springframework.validation.BindingResult;
38  import org.springframework.web.bind.annotation.*;
39  
40  import javax.servlet.http.HttpServletRequest;
41  import javax.servlet.http.HttpServletResponse;
42  import java.io.IOException;
43  import java.util.ArrayList;
44  import java.util.Collections;
45  import java.util.Comparator;
46  import java.util.List;
47  
48  @Controller
49  @RequestMapping(value = "/statusview/**")
50  public class StatePropagationTestController extends UifControllerBase {
51      private transient AcademicCalendarService academicCalendarService;
52      private transient CourseOfferingService courseOfferingService;
53      private transient StateService stateService;
54      private transient SchedulingService schedulingService;
55      private transient CourseOfferingSetService courseOfferingSetService;
56  
57      private static final Logger LOG = Logger.getLogger(StatePropagationTestController.class);
58  
59      public ContextInfo getContextInfo() {
60           return ContextUtils.createDefaultContextInfo();
61       }
62  
63      protected AcademicCalendarService getAcademicCalendarService(){
64          if(academicCalendarService == null) {
65              academicCalendarService = CourseOfferingResourceLoader.loadAcademicCalendarService();
66          }
67          return academicCalendarService;
68      }
69  
70     protected CourseOfferingService getCourseOfferingService() {
71         if(courseOfferingService == null){
72              courseOfferingService = CourseOfferingResourceLoader.loadCourseOfferingService();
73          }
74         return courseOfferingService;
75      }
76  
77     protected StateService getStateService() {
78          if(stateService == null) {
79              stateService = CourseOfferingResourceLoader.loadStateService();
80          }
81          return this.stateService;
82      }
83  
84      protected SchedulingService getSchedulingService() {
85           if(schedulingService == null){
86               schedulingService =  CourseOfferingResourceLoader.loadSchedulingService();
87           }
88           return schedulingService;
89       }
90  
91       protected CourseOfferingSetService getCourseOfferingSetService(){
92          if (courseOfferingSetService == null){
93              courseOfferingSetService = CourseOfferingResourceLoader.loadCourseOfferingSetService();
94          }
95          return courseOfferingSetService;
96      }
97      @Override
98      protected UifFormBase createInitialForm(HttpServletRequest request) {
99          return new UifFormBase();
100     }
101 
102     @RequestMapping(value = "/statusview/{termCode}/{coCode}", method = RequestMethod.GET)
103         @ResponseBody
104         public String showAOStates(@PathVariable("termCode") String termCode, @PathVariable("coCode") String coCode, @ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
105                           HttpServletRequest request, HttpServletResponse response) throws IOException {
106         return showAOStates(termCode, coCode, StringUtils.EMPTY, form, result, request, response);
107     }
108 
109     @RequestMapping(value = "/statusview/{termCode}/{coCode}/{aoCode}", method = RequestMethod.GET)
110     @ResponseBody
111     public String showAOStates(@PathVariable("termCode") String termCode, @PathVariable("coCode") String coCode, @PathVariable("aoCode") String aoCode, @ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
112                       HttpServletRequest request, HttpServletResponse response) throws IOException {
113 
114         StringBuilder stringBuilder = new StringBuilder();
115         List<TermInfo> termList;
116 
117         boolean displayAllAOs = StringUtils.isBlank(aoCode);
118 
119         try{
120             termList = findTermByTermCode(termCode);
121         } catch (Exception e) {
122             LOG.error("Error calling findTermByTermCode - " + termCode);
123             return "Error calling findTermByTermCode - " + termCode + " " + e.getMessage();
124         }
125 
126         if (termList != null && !termList.isEmpty()){
127             if( termList.size() == 1) {
128                 loadSocByTerm(stringBuilder, termList.get(0).getId());
129 
130                 CourseOfferingInfo courseOffering;
131                 try{
132                     //load courseoffing based on term and coCode
133                     courseOffering = loadCourseOfferingByTermAndCoCode(termList.get(0).getId(), coCode);
134                     appendHtmlSpanForState(stringBuilder, "course_offering", coCode + " " + getStateName(courseOffering.getStateKey()));
135 
136                     stringBuilder.append("<table id=\"ao_list\" border=\"1\">");
137                     stringBuilder.append("<tr><th>AO Code</th><th>AO State</th><th>FO State</th><th>AO Scheduling State</th><th>Registration Group</th><th>Seat pool</th></tr>");
138                     if (displayAllAOs){
139                         List<ActivityOfferingInfo> aoInfos = getCourseOfferingService().getActivityOfferingsByCourseOffering(courseOffering.getId(), getContextInfo());
140                         for (ActivityOfferingInfo aoInfo : aoInfos) {
141                             displayAO(stringBuilder,coCode,termCode,aoInfo);
142                         }
143                     } else {
144                         ActivityOfferingInfo activityOffering = loadActivityOfferingByCOAndAoCode(courseOffering.getId(), aoCode);
145                         displayAO(stringBuilder,coCode,termCode,activityOffering);
146                     }
147                     stringBuilder.append("</table>");
148                  } catch (Exception e) {
149                     LOG.error("Error calling loadCourseOfferingByTermAndCoCode - " + termCode + "/" + coCode);
150                     return "Error calling loadCourseOfferingByTermAndCoCode - " + termCode + "/" + coCode + " " + e.getMessage();
151                  }
152 
153             } else {
154                 LOG.error("Error: Found more than one Term for term code: " + termCode);
155                 return "Error: Found more than one Term for term code: " + termCode;
156              }
157         } else {
158             LOG.error("Error: Can't find any Term for term code: " + termCode);
159             return "Error: Can't find any Term for term code: " + termCode;
160         }
161 
162         response.setHeader("content-type", "text/html");
163 
164         return stringBuilder.toString();
165     }
166 
167     private void displayAO(StringBuilder stringBuilder, String coCode, String termCode, ActivityOfferingInfo activityOffering) throws Exception{
168         //load activityOffering based on aoCode
169 
170         FormatOfferingInfo formatOffering = getCourseOfferingService().getFormatOffering(activityOffering.getFormatOfferingId(), getContextInfo());
171 
172         stringBuilder.append("<tr>");
173         stringBuilder.append(getHTMLTableCell(activityOffering.getActivityCode()));
174         stringBuilder.append(getHTMLTableCell(getStateName(activityOffering.getStateKey())));
175 
176         if(formatOffering != null){
177             stringBuilder.append(getHTMLTableCell(getStateName(formatOffering.getStateKey())));
178         }else {
179             stringBuilder.append(getHTMLTableCell("Not found"));
180         }
181 
182         stringBuilder.append(getHTMLTableCell(getStateName(activityOffering.getSchedulingStateKey())));
183 
184         loadRegGroup(stringBuilder, activityOffering.getId());
185         loadSeatPool(stringBuilder, activityOffering.getId());
186 
187         stringBuilder.append("</tr>");
188     }
189 
190     private List<TermInfo> findTermByTermCode(String termCode) throws Exception {
191        QueryByCriteria.Builder qbcBuilder = QueryByCriteria.Builder.create();
192        qbcBuilder.setPredicates(PredicateFactory.equal("atpCode", termCode));
193        QueryByCriteria criteria = qbcBuilder.build();
194 
195        // Do search.  In ideal case, terms returns one element, which is the desired term.
196        AcademicCalendarService acalService = getAcademicCalendarService();
197        return acalService.searchForTerms(criteria, getContextInfo());
198     }
199 
200     private CourseOfferingInfo loadCourseOfferingByTermAndCoCode(String termId, String coCode) throws Exception {
201         CourseOfferingInfo courseOffering;
202 
203         // Building a query
204         QueryByCriteria.Builder qbcBuilder = QueryByCriteria.Builder.create();
205         qbcBuilder.setPredicates(PredicateFactory.and(
206                 PredicateFactory.equal("courseOfferingCode", coCode),
207                 PredicateFactory.equalIgnoreCase("atpId", termId)));
208         QueryByCriteria criteria = qbcBuilder.build();
209         List<String> courseOfferingIds = getCourseOfferingService().searchForCourseOfferingIds(criteria, getContextInfo());
210 
211         if(courseOfferingIds.size() > 0){
212             if(courseOfferingIds.size() == 1){
213                  courseOffering = getCourseOfferingService().getCourseOffering(courseOfferingIds.get(0), getContextInfo());
214 
215             } else {
216                 LOG.error("Error: Found more than one CourseOffering for CourseOffering code: " + coCode);
217                 throw new Exception ("Error: Found more than one CourseOffering for CourseOffering code: " + coCode);
218              }
219         } else {
220             LOG.error("Error: Can't find any Course Offering for a CourseOffering Code: " + coCode + " in term: " + termId);
221             throw new Exception("Error: Can't find any Course Offering for a CourseOffering Code: " + coCode + " in term: " + termId);
222         }
223 
224         return courseOffering;
225     }
226 
227 
228     private ActivityOfferingInfo loadActivityOfferingByCOAndAoCode(String coId, String aoCode)throws Exception {
229         ActivityOfferingInfo aoInfo = null;
230         List<ActivityOfferingInfo> aoInfos = getCourseOfferingService().getActivityOfferingsByCourseOffering(coId, getContextInfo());
231         if (StringUtils.isNotBlank(aoCode)){
232             for (ActivityOfferingInfo info : aoInfos) {
233                     if (info.getActivityCode().equals(aoCode)) {
234                         aoInfo = info;
235                     }
236             }
237         }
238 
239         return aoInfo;
240     }
241 
242     private String getStateName(String stateKey) throws Exception {
243         StateInfo state = getStateService().getState(stateKey, getContextInfo());
244         return state.getName();
245     }
246 
247     private void loadSeatPool(StringBuilder stringBuilder, String aoId) throws Exception{
248         List<SeatPoolDefinitionInfo> seatPoolDefinitionInfoList;
249         try {
250             seatPoolDefinitionInfoList = getCourseOfferingService().getSeatPoolDefinitionsForActivityOffering(aoId, getContextInfo());
251         } catch (Exception e) {
252             LOG.error("Error calling getSeatPoolDefinitionsForActivityOffering - " + aoId);
253             stringBuilder.append("Error calling Seat Pool");
254             stringBuilder.append("</br>");
255             return;
256         }
257 
258         //Sort the seatpools by priority order
259         Collections.sort(seatPoolDefinitionInfoList, new Comparator<SeatPoolDefinitionInfo>() {
260             @Override
261             public int compare(SeatPoolDefinitionInfo sp1, SeatPoolDefinitionInfo sp2) {
262                 return sp1.getProcessingPriority().compareTo(sp2.getProcessingPriority());
263             }
264         });
265 
266         if(seatPoolDefinitionInfoList.size() > 0) {
267             StringBuilder sb = new StringBuilder();
268             for(SeatPoolDefinitionInfo spd : seatPoolDefinitionInfoList){
269                 sb.append(spd.getProcessingPriority() + " - " + spd.getStateKey() + "</br>");
270             }
271             stringBuilder.append(getHTMLTableCell(sb.toString()));
272         } else {
273             stringBuilder.append(getHTMLTableCell("No Data"));
274         }
275 
276     }
277 
278     private SocInfo loadSocByTerm(StringBuilder stringBuilder, String termId){
279         List<String> socIds;
280         SocInfo soc = null;
281         try {
282             socIds = getCourseOfferingSetService().getSocIdsByTerm(termId, getContextInfo());
283         } catch (Exception e) {
284             LOG.error("Error calling getSocIdsByTerm - " + termId);
285             stringBuilder.append("\n" )
286                             .append( "Error calling SOC: " )
287                             .append( e.getMessage() );
288             return null;
289         }
290 
291         if (socIds != null && !socIds.isEmpty()){
292             //For M5, it should have only one SOC
293             if (socIds.size() > 1){
294                 LOG.error("More than one SOC found for a term");
295                 stringBuilder.append("\n Error calling SOC: More than one SOC found for a term");
296                 return null;
297             }
298 
299 
300             try {
301                 soc = getCourseOfferingSetService().getSoc(socIds.get(0), getContextInfo());
302                 appendHtmlSpanForState(stringBuilder, "soc", getStateName(soc.getStateKey()));
303                 appendHtmlSpanForState(stringBuilder, "soc_scheduling", getStateName(soc.getSchedulingStateKey()));
304             } catch (Exception e) {
305                 LOG.error("Error calling getSoc - " + socIds.get(0));
306                 stringBuilder.append("\n")
307                                 .append( "Error calling SOC: " )
308                                 .append( e.getMessage() );
309                 return null;
310             }
311         }
312 
313         return soc;
314 
315     }
316 
317     private static StringBuilder appendHtmlSpanForState(StringBuilder stringBuilder, String domId, String value) {
318 
319         if( stringBuilder == null ) stringBuilder = new StringBuilder();
320 
321         if( domId == null || value == null ) return stringBuilder;
322         domId = domId.trim();
323         value = value.trim();
324 
325         stringBuilder.append( "<span" )
326                         .append( " id=" )
327                         .append( "\"")
328                         .append( domId.trim() )
329                         .append( "\"")
330                         .append( ">");
331         stringBuilder.append( value.trim() );
332         stringBuilder.append( "</span>" );
333         stringBuilder.append( "<br/>" );
334 
335         return stringBuilder;
336     }
337 
338     private void loadRegGroup(StringBuilder stringBuilder, String aoId){
339 
340         try {
341             List<RegistrationGroupInfo>  registrationGroupInfos = getCourseOfferingService().getRegistrationGroupsByActivityOffering(aoId, getContextInfo());
342             if(registrationGroupInfos.size()>0){
343                 StringBuilder sb = new StringBuilder();
344                 for(RegistrationGroupInfo rg : registrationGroupInfos){
345                     sb.append(rg.getId() + " - " + getStateName(rg.getStateKey()) + "</br>");
346                 }
347                 stringBuilder.append(getHTMLTableCell(sb.toString()));
348             }else{
349                 stringBuilder.append(getHTMLTableCell("No Data"));
350             }
351         } catch (Exception e) {
352             LOG.error("Error calling getRegistrationGroupsByActivityOffering - " + aoId);
353             stringBuilder.append("Error calling SOC: " )
354                             .append(e.getMessage())
355                             .append("</br>");
356         }
357     }
358 
359     private String getHTMLTableCell(String data){
360         return "<td>" + data + "</td>";
361     }
362 
363 }