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