1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.enrollment.class2.courseoffering.util;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.kim.api.identity.Person;
20 import org.kuali.rice.kim.api.identity.PersonService;
21 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
22 import org.kuali.rice.kim.impl.KIMPropertyConstants;
23 import org.kuali.student.enrollment.class2.courseoffering.dto.CourseOfferingListSectionWrapper;
24 import org.kuali.student.enrollment.class2.scheduleofclasses.dto.ActivityOfferingDisplayWrapper;
25 import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
26 import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingCrossListingInfo;
27 import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
28 import org.kuali.student.enrollment.courseoffering.dto.FormatOfferingInfo;
29 import org.kuali.student.enrollment.courseoffering.dto.OfferingInstructorInfo;
30 import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
31 import org.kuali.student.r2.common.dto.ContextInfo;
32 import org.kuali.student.r2.common.dto.StatusInfo;
33 import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
34 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
35 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
36 import org.kuali.student.r2.common.exceptions.MissingParameterException;
37 import org.kuali.student.r2.common.exceptions.OperationFailedException;
38 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
39 import org.kuali.student.r2.common.exceptions.ReadOnlyException;
40 import org.kuali.student.r2.common.exceptions.VersionMismatchException;
41 import org.kuali.student.r2.common.util.ContextUtils;
42 import org.kuali.student.r2.common.util.constants.CourseOfferingServiceConstants;
43 import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
44 import org.kuali.student.r2.core.acal.dto.TermInfo;
45 import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
46 import org.kuali.student.r2.core.class1.search.ActivityOfferingSearchServiceImpl;
47 import org.kuali.student.r2.core.class1.search.CourseOfferingManagementSearchImpl;
48 import org.kuali.student.r2.core.class1.type.dto.TypeTypeRelationInfo;
49 import org.kuali.student.r2.core.class1.type.service.TypeService;
50 import org.kuali.student.r2.core.constants.TypeServiceConstants;
51 import org.kuali.student.r2.core.scheduling.dto.ScheduleRequestSetInfo;
52 import org.kuali.student.r2.core.scheduling.service.SchedulingService;
53 import org.kuali.student.r2.core.search.dto.SearchParamInfo;
54 import org.kuali.student.r2.core.search.dto.SearchRequestInfo;
55 import org.kuali.student.r2.core.search.dto.SearchResultCellInfo;
56 import org.kuali.student.r2.core.search.dto.SearchResultInfo;
57 import org.kuali.student.r2.core.search.dto.SearchResultRowInfo;
58 import org.kuali.student.r2.core.search.service.SearchService;
59 import org.kuali.student.r2.lum.clu.service.CluService;
60 import org.kuali.student.r2.lum.course.dto.ActivityInfo;
61 import org.kuali.student.r2.lum.course.dto.CourseInfo;
62 import org.kuali.student.r2.lum.course.dto.FormatInfo;
63 import org.kuali.student.r2.lum.course.service.CourseService;
64
65 import java.io.Serializable;
66 import java.util.ArrayList;
67 import java.util.Arrays;
68 import java.util.Calendar;
69 import java.util.Collection;
70 import java.util.Collections;
71 import java.util.Comparator;
72 import java.util.Date;
73 import java.util.HashMap;
74 import java.util.List;
75 import java.util.Map;
76
77
78
79
80
81
82 public class CourseOfferingViewHelperUtil {
83
84 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CourseOfferingViewHelperUtil.class);
85
86 public static List<Person> getInstructorByPersonId(String personId){
87 Map<String, String> searchCriteria = new HashMap<String, String>();
88 searchCriteria.put(KIMPropertyConstants.Person.PRINCIPAL_ID, personId);
89 List<Person> lstPerson = getPersonService().findPeople(searchCriteria);
90 return lstPerson;
91 }
92
93 public static PersonService getPersonService() {
94 return KimApiServiceLocator.getPersonService();
95 }
96
97 public static String trimTrailing0(String creditValue){
98 if (creditValue.indexOf(".0") > 0) {
99 return creditValue.substring(0, creditValue.length( )- 2);
100 } else {
101 return creditValue;
102 }
103 }
104
105 public static OfferingInstructorInfo findDisplayInstructor(List<OfferingInstructorInfo> instructors) {
106 OfferingInstructorInfo result = null;
107
108 if(instructors != null && !instructors.isEmpty()) {
109
110
111 Collection<OfferingInstructorInfo> highestInstEffortInstructors = new ArrayList<OfferingInstructorInfo>();
112 float highestInstEffortComparison = 0f;
113
114 for (OfferingInstructorInfo instructor : instructors) {
115 if(instructor.getPercentageEffort() != null){
116
117
118 if(instructor.getPercentageEffort() > highestInstEffortComparison) {
119 highestInstEffortInstructors.clear();
120 highestInstEffortComparison = instructor.getPercentageEffort();
121 highestInstEffortInstructors.add(instructor);
122 }
123
124
125 else if (instructor.getPercentageEffort() == highestInstEffortComparison) {
126 highestInstEffortInstructors.add(instructor);
127 }
128 }
129 }
130
131 if(highestInstEffortInstructors.size() == 1) {
132 result = highestInstEffortInstructors.iterator().next();
133 }
134 else {
135 List<String> names = new ArrayList<String>(highestInstEffortInstructors.size());
136 Map<String, OfferingInstructorInfo> nameMap = new HashMap<String, OfferingInstructorInfo>(highestInstEffortInstructors.size());
137 for(OfferingInstructorInfo oiInfo : highestInstEffortInstructors) {
138 names.add(oiInfo.getPersonName());
139 nameMap.put(oiInfo.getPersonName(), oiInfo);
140 }
141
142 Collections.sort(names);
143 int firstName = 0;
144 result = nameMap.get(names.get(firstName));
145 }
146 }
147
148 return result;
149 }
150
151 public static CourseOfferingListSectionWrapper convertCourseOffering2ListSectionWrapper(CourseOfferingInfo coInfo){
152 CourseOfferingListSectionWrapper coWrapper = new CourseOfferingListSectionWrapper();
153 coWrapper.setSubjectArea(coInfo.getSubjectArea());
154 coWrapper.setCourseOfferingCode(coInfo.getCourseOfferingCode());
155 coWrapper.setCourseOfferingCreditOptionKey(coInfo.getCreditOptionId());
156 coWrapper.setCourseOfferingGradingOptionKey(coInfo.getGradingOptionId());
157 coWrapper.setCourseOfferingStateKey(coInfo.getStateKey());
158 coWrapper.setCourseOfferingDesc(coInfo.getCourseOfferingTitle());
159 coWrapper.setCourseOfferingId(coInfo.getId());
160 return coWrapper;
161 }
162
163 public static void updateCourseOfferingStateFromActivityOfferingStateChange(CourseOfferingInfo coInfo, ContextInfo context) throws InvalidParameterException, MissingParameterException, DoesNotExistException, PermissionDeniedException, OperationFailedException, DataValidationErrorException, VersionMismatchException, ReadOnlyException {
164 updateCourseOfferingStateFromActivityOfferingStateChange(convertCourseOffering2ListSectionWrapper(coInfo),context);
165 }
166
167
168
169
170
171
172
173
174
175 public static void updateCourseOfferingStateFromActivityOfferingStateChange(CourseOfferingListSectionWrapper coInfo, ContextInfo context) throws InvalidParameterException, MissingParameterException, DoesNotExistException, PermissionDeniedException, OperationFailedException, DataValidationErrorException, VersionMismatchException, ReadOnlyException {
176
177 List<FormatOfferingInfo> formatOfferings = CourseOfferingManagementUtil.getCourseOfferingService().getFormatOfferingsByCourseOffering(coInfo.getCourseOfferingId(), context);
178
179 String oldFoState, newFoState;
180
181
182 for (FormatOfferingInfo fo : formatOfferings) {
183 oldFoState = fo.getStateKey();
184 List<ActivityOfferingInfo> activityOfferings = CourseOfferingManagementUtil.getCourseOfferingService().getActivityOfferingsByFormatOffering(fo.getId(), context);
185 newFoState = getNewFoState(activityOfferings);
186
187 if (newFoState != null && !StringUtils.equals(oldFoState, newFoState)) {
188 fo.setStateKey(newFoState);
189 StatusInfo statusInfo = CourseOfferingManagementUtil.getCourseOfferingService().changeFormatOfferingState(fo.getId(), newFoState, context);
190 if (!statusInfo.getIsSuccess()){
191 throw new RuntimeException(statusInfo.getMessage());
192 }
193 }
194 }
195 }
196
197
198
199
200
201
202
203
204
205 public static String getNewFoState(List<ActivityOfferingInfo> activityOfferings) {
206 boolean draftState= false;
207 boolean plannedState= false;
208 boolean offeredState= false;
209 boolean cancelledState= false;
210 boolean suspendedState= false;
211
212 if(activityOfferings == null || activityOfferings.size() == 0) {
213 return LuiServiceConstants.LUI_FO_STATE_DRAFT_KEY;
214 }
215
216 for (ActivityOfferingInfo ao : activityOfferings) {
217 if (StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_APPROVED_KEY, ao.getStateKey()) ||
218 StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_SUBMITTED_KEY, ao.getStateKey()) ) {
219 plannedState = true;
220 } else if (StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_OFFERED_KEY, ao.getStateKey())) {
221 offeredState = true;
222 } else if (StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_CANCELED_KEY, ao.getStateKey())) {
223 cancelledState = true;
224 } else if (StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_DRAFT_KEY, ao.getStateKey())) {
225 draftState = true;
226 } else if (StringUtils.equals(LuiServiceConstants.LUI_AO_STATE_SUSPENDED_KEY, ao.getStateKey())) {
227 suspendedState = true;
228 }
229 }
230
231
232 if (offeredState) {
233 return LuiServiceConstants.LUI_FO_STATE_OFFERED_KEY;
234 } else if (plannedState) {
235 return LuiServiceConstants.LUI_FO_STATE_PLANNED_KEY;
236 } else if (draftState) {
237 return LuiServiceConstants.LUI_FO_STATE_DRAFT_KEY;
238 } else if (suspendedState) {
239 return LuiServiceConstants.LUI_FO_STATE_SUSPENDED_KEY;
240 }
241
242
243 if (cancelledState) {
244 return LuiServiceConstants.LUI_FO_STATE_CANCELED_KEY;
245 }
246
247 return null;
248 }
249
250 public static String createTheCrossListedCos(CourseOfferingInfo coToShow){
251 if (coToShow != null && coToShow.getCrossListings() != null && coToShow.getCrossListings().size() > 0) {
252
253
254 StringBuilder crossListedCodes = new StringBuilder();
255
256 for (CourseOfferingCrossListingInfo courseInfo : coToShow.getCrossListings()) {
257 crossListedCodes.append(courseInfo.getCode());
258 crossListedCodes.append(" ");
259 }
260 return crossListedCodes.toString();
261 }
262 return null;
263 }
264
265
266
267
268
269
270 public static String createColocatedDisplayData(ActivityOfferingInfo ao, ContextInfo context) throws InvalidParameterException, MissingParameterException, PermissionDeniedException,
271 OperationFailedException, DoesNotExistException {
272
273
274 StringBuilder sb = new StringBuilder(" ");
275 List<ScheduleRequestSetInfo> scheduleRequestSets = CourseOfferingManagementUtil.getSchedulingService()
276 .getScheduleRequestSetsByRefObject(CourseOfferingServiceConstants.REF_OBJECT_URI_ACTIVITY_OFFERING, ao.getId(), context);
277 for(ScheduleRequestSetInfo srs : scheduleRequestSets) {
278 List<ActivityOfferingInfo> aoList = CourseOfferingManagementUtil.getCourseOfferingService().getActivityOfferingsByIds(srs.getRefObjectIds(), context);
279 for(ActivityOfferingInfo aoInfo : aoList) {
280 sb.append(aoInfo.getCourseOfferingCode() + " " + aoInfo.getActivityCode() + ActivityOfferingDisplayWrapper.BR);
281 }
282 }
283 return sb.toString();
284 }
285
286
287
288
289
290
291
292 public static List<CourseInfo> getMatchingCoursesFromClu(String courseName) {
293
294 CourseInfo returnCourseInfo;
295 String courseId;
296 List<SearchParamInfo> searchParams = new ArrayList<SearchParamInfo>();
297 List<CourseInfo> courseInfoList = new ArrayList<CourseInfo>();
298
299 SearchParamInfo qpv1 = new SearchParamInfo();
300 qpv1.setKey("lu.queryParam.startsWith.cluCode");
301 qpv1.getValues().add(courseName.toUpperCase());
302 searchParams.add(qpv1);
303
304 SearchParamInfo qpv2 = new SearchParamInfo();
305 qpv2.setKey("lu.queryParam.cluState");
306 qpv2.setValues(Arrays.asList("Active"));
307 searchParams.add(qpv2);
308
309 SearchRequestInfo searchRequest = new SearchRequestInfo();
310 searchRequest.setParams(searchParams);
311 searchRequest.setSearchKey("lu.search.cluByCodeAndState");
312
313 try {
314 SearchResultInfo searchResult = CourseOfferingManagementUtil.getCluService().search(searchRequest, ContextUtils.getContextInfo());
315 if (searchResult.getRows().size() > 0) {
316 for (SearchResultRowInfo row : searchResult.getRows()) {
317 List<SearchResultCellInfo> srCells = row.getCells();
318 if (srCells != null && srCells.size() > 0) {
319 for (SearchResultCellInfo cell : srCells) {
320 if ("lu.resultColumn.cluId".equals(cell.getKey())) {
321 courseId = cell.getValue();
322 returnCourseInfo = CourseOfferingManagementUtil.getCourseService().getCourse(courseId, ContextUtils.getContextInfo());
323 courseInfoList.add(returnCourseInfo);
324 }
325 }
326 }
327 }
328 }
329 } catch (Exception e) {
330 throw new RuntimeException(e);
331 }
332
333 return courseInfoList;
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347
348 public static void addActivityOfferingTypesToFormatOffering(FormatOfferingInfo fo, CourseInfo course,
349 TypeService typeService, ContextInfo context)
350 throws PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException,
351 DoesNotExistException {
352 if (fo.getActivityOfferingTypeKeys() != null && !fo.getActivityOfferingTypeKeys().isEmpty()) {
353
354 return;
355 }
356 List<FormatInfo> formats = course.getFormats();
357 FormatInfo format = null;
358 for (FormatInfo f: formats) {
359 if (f.getId().equals(fo.getFormatId())) {
360
361 format = f;
362 break;
363 }
364 }
365
366 List<String> activityTypes = new ArrayList<String>();
367 for (ActivityInfo activityInfo: format.getActivities()) {
368 activityTypes.add(activityInfo.getTypeKey());
369 }
370
371 List<String> aoTypeKeys = new ArrayList<String>();
372 for (String activityType: activityTypes) {
373 List<TypeTypeRelationInfo> typeTypeRels =
374 typeService.getTypeTypeRelationsByOwnerAndType(activityType,
375 TypeServiceConstants.TYPE_TYPE_RELATION_ALLOWED_TYPE_KEY,
376 context);
377 if (typeTypeRels.size() != 1) {
378
379
380
381 throw new UnsupportedOperationException("Can't handle Activity Type -> AO Type that isn't 1-1. Search for this message in Java code");
382 } else {
383 String aoType = typeTypeRels.get(0).getRelatedTypeKey();
384 aoTypeKeys.add(aoType);
385 }
386 }
387
388 fo.setActivityOfferingTypeKeys(aoTypeKeys);
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 public static int calculateTermDayOfYear( TermInfo termInfo, AcademicCalendarService academicCalendarService, ContextInfo contextInfo )
405 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
406
407 int termDayOfYear = 0;
408
409
410 if(termInfo.getStartDate() != null
411 && termInfo.getEndDate() != null )
412 {
413 Date termClassStartDate = termInfo.getStartDate();
414 Date termClassEndDate = termInfo.getEndDate();
415 Date avgDate = new Date( termClassStartDate.getTime() + ( (termClassEndDate.getTime() - termClassStartDate.getTime()) /2 ) );
416 Calendar cal = Calendar.getInstance();
417 cal.setTime( avgDate) ;
418 termDayOfYear = cal.get( Calendar.DAY_OF_YEAR );
419 }
420
421 return termDayOfYear;
422 }
423
424 public static List<CourseOfferingInfo> loadCourseOfferings(SearchRequestInfo searchRequest) throws InvalidParameterException, MissingParameterException, PermissionDeniedException, OperationFailedException {
425 List<CourseOfferingInfo> result = new ArrayList<CourseOfferingInfo>();
426 ContextInfo contextInfo = new ContextInfo();
427 SearchResultInfo searchResult = CourseOfferingManagementUtil.getSearchService().search(searchRequest, contextInfo);
428
429 for( SearchResultRowInfo row : searchResult.getRows() ) {
430 CourseOfferingInfo courseOfferingInfo = new CourseOfferingInfo();
431 for( SearchResultCellInfo cellInfo : row.getCells() ) {
432 String value = StringUtils.defaultIfEmpty( cellInfo.getValue(), StringUtils.EMPTY );
433 if( CourseOfferingManagementSearchImpl.SearchResultColumns.CODE.equals( cellInfo.getKey() ) ) {
434 courseOfferingInfo.setCourseOfferingCode( value );
435 }
436 else if( CourseOfferingManagementSearchImpl.SearchResultColumns.CO_ID.equals( cellInfo.getKey() ) ) {
437 courseOfferingInfo.setId( value );
438 }
439 }
440 result.add( courseOfferingInfo );
441 }
442 return result;
443 }
444
445 public static List<ActivityOfferingInfo> loadActivityOfferings(SearchRequestInfo searchRequest) throws InvalidParameterException, MissingParameterException, PermissionDeniedException, OperationFailedException {
446 List<ActivityOfferingInfo> result = new ArrayList<ActivityOfferingInfo>();
447 ContextInfo contextInfo = new ContextInfo();
448 SearchResultInfo searchResult = CourseOfferingManagementUtil.getSearchService().search(searchRequest, contextInfo);
449 List<SearchResultRowInfo> rows = searchResult.getRows();
450 if (!rows.isEmpty()) {
451 for (SearchResultRowInfo row: rows) {
452 List<SearchResultCellInfo> cells = row.getCells();
453 String aoId = null;
454 String aoCode = null;
455 String aoType = null;
456 for (SearchResultCellInfo cell: cells) {
457 if (cell.getKey().equals(ActivityOfferingSearchServiceImpl.SearchResultColumns.AO_ID)) {
458 aoId = cell.getValue();
459 } else if (cell.getKey().equals(ActivityOfferingSearchServiceImpl.SearchResultColumns.AO_CODE)) {
460 aoCode = cell.getValue();
461 } else if (cell.getKey().equals(ActivityOfferingSearchServiceImpl.SearchResultColumns.AO_TYPE)) {
462 aoType = cell.getValue();
463 } else {
464 throw new OperationFailedException("Query for AO id, code, and type returned too many columns.");
465 }
466 }
467 ActivityOfferingInfo aoLimitedInfo = new ActivityOfferingInfo();
468 aoLimitedInfo.setActivityCode(aoCode);
469 aoLimitedInfo.setId(aoId);
470 aoLimitedInfo.setTypeKey(aoType);
471 result.add(aoLimitedInfo);
472 }
473 }
474
475 if(result.size() > 1) {
476 Collections.sort(result, new ActivityOfferingComparator());
477 }
478
479 return result;
480 }
481
482 private static class ActivityOfferingComparator implements Comparator<ActivityOfferingInfo>, Serializable {
483 @Override
484 public int compare(ActivityOfferingInfo o1, ActivityOfferingInfo o2) {
485 String value1 = o1.getActivityCode();
486 String value2 = o2.getActivityCode();
487
488 int result = value1.compareToIgnoreCase(value2);
489 return result;
490 }
491 }
492 }