1
2
3
4
5 package org.kuali.student.enrollment.class2.courseofferingset.service.impl;
6
7 import java.util.ArrayList;
8 import java.util.Date;
9 import java.util.List;
10
11 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
12 import org.kuali.student.enrollment.acal.dto.TermInfo;
13 import org.kuali.student.enrollment.acal.service.AcademicCalendarService;
14 import org.kuali.student.enrollment.class2.courseofferingset.dao.SocDao;
15 import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
16 import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
17 import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
18 import org.kuali.student.enrollment.courseofferingset.dto.SocInfo;
19 import org.kuali.student.enrollment.courseofferingset.dto.SocRolloverResultInfo;
20 import org.kuali.student.enrollment.courseofferingset.service.CourseOfferingSetService;
21 import org.kuali.student.enrollment.courseofferingset.service.CourseOfferingSetServiceBusinessLogic;
22 import org.kuali.student.r2.lum.course.service.CourseService;
23 import org.kuali.student.r2.common.dto.ContextInfo;
24 import org.kuali.student.r2.common.exceptions.*;
25 import org.kuali.student.r2.common.util.constants.CourseOfferingSetServiceConstants;
26 import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
27
28 import javax.xml.namespace.QName;
29
30 public class CourseOfferingSetServiceBusinessLogicImpl implements CourseOfferingSetServiceBusinessLogic {
31
32 private CourseOfferingService coService;
33 private CourseService courseService;
34 private AcademicCalendarService acalService;
35 private CourseOfferingSetService socService;
36 private SocDao socDao;
37
38 public SocDao getSocDao() {
39 return socDao;
40 }
41
42 public void setSocDao(SocDao socDao) {
43 this.socDao = socDao;
44 }
45
46 public CourseOfferingSetService getSocService() {
47 return socService;
48 }
49
50 public void setSocService(CourseOfferingSetService socService) {
51 this.socService = socService;
52 }
53
54 public CourseOfferingService getCoService() {
55 return coService;
56 }
57
58 public void setCoService(CourseOfferingService coService) {
59 this.coService = coService;
60 }
61
62 public CourseService getCourseService() {
63 return courseService;
64 }
65
66 public void setCourseService(CourseService courseService) {
67 this.courseService = courseService;
68 }
69
70 public AcademicCalendarService getAcalService() {
71 return acalService;
72 }
73
74 public void setAcalService(AcademicCalendarService acalService) {
75 this.acalService = acalService;
76 }
77
78 private CourseOfferingSetService _getSocService() {
79
80 if (socService == null) {
81 socService = (CourseOfferingSetService) GlobalResourceLoader.getService(new QName(CourseOfferingSetServiceConstants.NAMESPACE,
82 CourseOfferingSetServiceConstants.SERVICE_NAME_LOCAL_PART));
83 }
84 return socService;
85 }
86
87 private SocInfo _findTargetSoc(String targetTermId) {
88 try {
89 List<String> socIds = this._getSocService().getSocIdsByTerm(targetTermId, new ContextInfo());
90 if (socIds != null) {
91 if (socIds.isEmpty()) {
92 return null;
93 }
94 for (String socId: socIds) {
95 SocInfo targetSoc = this._getSocService().getSoc(socId, new ContextInfo());
96 if (targetSoc.getTypeKey().equals(CourseOfferingSetServiceConstants.MAIN_SOC_TYPE_KEY)) {
97 return targetSoc;
98 }
99 }
100 }
101 return null;
102 } catch (Exception e) {
103 return null;
104 }
105 }
106
107 private boolean _hasOfferingsInTargetTerm(TermInfo targetTerm) {
108 if (socDao == null) {
109 return false;
110 }
111 Long count = socDao.countLuisByTypeForTermId(LuiServiceConstants.COURSE_OFFERING_TYPE_KEY, targetTerm.getId());
112 return count > 0;
113 }
114
115 @Override
116 public SocInfo rolloverSoc(String sourceSocId, String targetTermId, List<String> optionKeys, ContextInfo context)
117 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
118 PermissionDeniedException {
119
120 TermInfo targetTerm = this.acalService.getTerm(targetTermId, context);
121 if (targetTerm == null) {
122 throw new DoesNotExistException("target term id (" + targetTermId + ") does not exist");
123 }
124
125 SocInfo sourceSoc = this._getSocService().getSoc(sourceSocId, context);
126 if (sourceSoc.getTermId().equals(targetTermId)) {
127 throw new InvalidParameterException("The term of the source soc and the target term must be different");
128 }
129
130
131
132 if (_hasOfferingsInTargetTerm(targetTerm)) {
133 throw new OperationFailedException("Can't rollover if course offerings exist in target term");
134 }
135
136 SocInfo targetSoc = _findTargetSoc(targetTermId);
137 boolean foundTargetSoc = true;
138 if (targetSoc == null) {
139
140 targetSoc = new SocInfo(sourceSoc);
141 foundTargetSoc = false;
142 targetSoc.setId(null);
143 targetSoc.setTermId(targetTermId);
144 targetSoc.setStateKey(CourseOfferingSetServiceConstants.DRAFT_SOC_STATE_KEY);
145 try {
146 targetSoc = this._getSocService().createSoc(targetSoc.getTermId(), targetSoc.getTypeKey(), targetSoc, context);
147 } catch (DataValidationErrorException ex) {
148 throw new OperationFailedException("Unexpected", ex);
149 } catch (ReadOnlyException ex) {
150 throw new OperationFailedException("Unexpected", ex);
151 }
152 } else {
153
154 targetSoc.setStateKey(CourseOfferingSetServiceConstants.DRAFT_SOC_STATE_KEY);
155 try {
156
157 this._getSocService().updateSoc(targetSoc.getId(), targetSoc, context);
158 } catch (DataValidationErrorException ex) {
159 throw new OperationFailedException("Unexpected", ex);
160 } catch (ReadOnlyException ex) {
161 throw new OperationFailedException("Unexpected", ex);
162 } catch (VersionMismatchException ex) {
163 throw new OperationFailedException("Unexpected", ex);
164 }
165 }
166
167
168
169 SocRolloverResultInfo result = new SocRolloverResultInfo();
170 result.setTypeKey(CourseOfferingSetServiceConstants.ROLLOVER_RESULT_TYPE_KEY);
171 result.setStateKey(CourseOfferingSetServiceConstants.SUBMITTED_RESULT_STATE_KEY);
172 result.setSourceSocId(sourceSocId);
173 result.setTargetTermId(targetTermId);
174 result.setOptionKeys(optionKeys);
175 result.setTargetSocId(targetSoc.getId());
176 Date now = new Date();
177 result.setDateInitiated(now);
178
179
180
181 result.setDateCompleted(now);
182 try {
183 result = this._getSocService().createSocRolloverResult(result.getTypeKey(), result, context);
184 } catch (DataValidationErrorException ex) {
185 throw new OperationFailedException("Unexpected", ex);
186 } catch (ReadOnlyException ex) {
187 throw new OperationFailedException("Unexpected", ex);
188 }
189
190 final CourseOfferingRolloverRunner runner = new CourseOfferingRolloverRunner();
191 runner.setContext(context);
192 runner.setCoService(coService);
193 runner.setCourseService(courseService);
194 runner.setAcalService(acalService);
195 runner.setSocService(this._getSocService());
196 runner.setResult(result);
197
198 if (optionKeys.contains(CourseOfferingSetServiceConstants.RUN_SYNCHRONOUSLY_OPTION_KEY)) {
199
200 runner.run();
201 } else {
202
203 KSThreadRunnerAfterTransactionSynchronization.runAfterTransactionCompletes(runner);
204 }
205 return targetSoc;
206 }
207
208 @Override
209 public SocRolloverResultInfo reverseRollover(String rolloverResultId, List<String> optionKeys, ContextInfo context)
210 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
211 PermissionDeniedException {
212 SocRolloverResultInfo rolloverResult = this._getSocService().getSocRolloverResult(rolloverResultId, context);
213 if (optionKeys.contains(CourseOfferingSetServiceConstants.REVERSE_JUST_CREATES_OPTION_KEY)) {
214 if (!rolloverResult.getOptionKeys().contains(CourseOfferingSetServiceConstants.LOG_SUCCESSES_OPTION_KEY)) {
215 throw new InvalidParameterException(
216 "You cannot reverse just the creates if the original rollover did not log the course offerings that it successfully created");
217 }
218 }
219 SocRolloverResultInfo reverseResult = new SocRolloverResultInfo(rolloverResult);
220 reverseResult.setTypeKey(CourseOfferingSetServiceConstants.ROLLOVER_RESULT_TYPE_KEY);
221 reverseResult.setStateKey(CourseOfferingSetServiceConstants.SUBMITTED_RESULT_STATE_KEY);
222 reverseResult.setOptionKeys(optionKeys);
223
224 try {
225 reverseResult = this._getSocService().createSocRolloverResult(reverseResult.getTypeKey(), reverseResult, context);
226 } catch (DataValidationErrorException ex) {
227 throw new OperationFailedException("Unexpected", ex);
228 } catch (ReadOnlyException ex) {
229 throw new OperationFailedException("Unexpected", ex);
230 }
231
232 CourseOfferingReverseRolloverRunner runner = new CourseOfferingReverseRolloverRunner();
233 runner.setContext(context);
234 runner.setCoService(coService);
235 runner.setSocService(this._getSocService());
236 runner.setCourseService(courseService);
237 runner.setAcalService(acalService);
238 runner.setRolloverResult(rolloverResult);
239 runner.setReverseResult(reverseResult);
240 if (optionKeys.contains(CourseOfferingSetServiceConstants.RUN_SYNCHRONOUSLY_OPTION_KEY)) {
241 runner.run();
242 } else {
243 Thread thread = new Thread(runner);
244 thread.start();
245 }
246 return reverseResult;
247 }
248
249 @Override
250 public List<String> getCourseOfferingIdsBySoc(String socId, ContextInfo context)
251 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
252 PermissionDeniedException {
253
254 SocInfo soc = this._getSocService().getSoc(socId, context);
255
256 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.MAIN_SOC_TYPE_KEY)) {
257 return coService.getCourseOfferingIdsByTerm(soc.getTermId(), Boolean.TRUE, context);
258 }
259
260 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.SUBJECT_AREA_SOC_TYPE_KEY)) {
261 return coService.getCourseOfferingIdsByTermAndSubjectArea(soc.getTermId(), soc.getSubjectArea(), context);
262 }
263
264 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.UNITS_CONTENT_OWNER_SOC_TYPE_KEY)) {
265 return coService.getCourseOfferingIdsByTermAndUnitsContentOwner(soc.getTermId(), soc.getUnitsContentOwnerId(), context);
266 }
267 throw new OperationFailedException(soc.getTypeKey() + " is an unsupported type for this implementation");
268
269
270
271
272
273
274
275 }
276
277 @Override
278 public Integer deleteCourseOfferingsBySoc(String socId, ContextInfo context)
279 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
280 PermissionDeniedException {
281
282
283 List<String> ids = this.getCourseOfferingIdsBySoc(socId, context);
284 for (String id : ids) {
285 try {
286 this.coService.deleteCourseOffering(socId, context);
287 } catch (DependentObjectsExistException e) {
288 throw new OperationFailedException(e.getMessage());
289 }
290 }
291 return ids.size();
292 }
293
294 @Override
295 public Boolean isCourseOfferingInSoc(String socId, String courseOfferingId, ContextInfo context)
296 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
297 PermissionDeniedException {
298
299 SocInfo soc = this._getSocService().getSoc(socId, context);
300 CourseOfferingInfo co = this.coService.getCourseOffering(courseOfferingId, context);
301
302 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.MAIN_SOC_TYPE_KEY)) {
303 if (co.getTermId().equals(soc.getTermId())) {
304 return true;
305 }
306
307 return false;
308 }
309
310 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.SUBJECT_AREA_SOC_TYPE_KEY)) {
311 if (co.getTermId().equals(soc.getTermId())) {
312 if (co.getSubjectArea().equals(soc.getSubjectArea())) {
313 return true;
314 }
315 }
316
317 return false;
318 }
319
320 if (soc.getTypeKey().equals(CourseOfferingSetServiceConstants.UNITS_CONTENT_OWNER_SOC_TYPE_KEY)) {
321 if (co.getTermId().equals(soc.getTermId())) {
322 if (co.getUnitsContentOwnerOrgIds().equals(soc.getUnitsContentOwnerId())) {
323 return true;
324 }
325 }
326
327 return false;
328 }
329
330 List<String> ids = this.getCourseOfferingIdsBySoc(socId, context);
331 return ids.contains(courseOfferingId);
332 }
333
334 @Override
335 public List<String> getPublishedCourseOfferingIdsBySoc(String socId, ContextInfo context)
336 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
337 PermissionDeniedException {
338 List<String> list = new ArrayList<String>();
339 List<String> list2 = this.getCourseOfferingIdsBySoc(socId, context);
340 for (CourseOfferingInfo info : this.coService.getCourseOfferingsByIds(list2, context)) {
341
342
343 list.add(info.getId());
344
345 }
346 return list;
347 }
348
349 @Override
350 public List<String> getUnpublishedCourseOfferingIdsBySoc(String socId, ContextInfo context)
351 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
352 PermissionDeniedException {
353 List<String> list = new ArrayList<String>();
354 List<String> list2 = this.getCourseOfferingIdsBySoc(socId, context);
355 for (CourseOfferingInfo info : this.coService.getCourseOfferingsByIds(list2, context)) {
356
357
358 list.add(info.getId());
359
360 }
361 return list;
362 }
363
364 @Override
365 public List<String> getUnpublishedActivityOfferingIdsBySoc(String socId, ContextInfo context)
366 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
367 PermissionDeniedException {
368 List<String> list = new ArrayList<String>();
369 List<String> list2 = this.getCourseOfferingIdsBySoc(socId, context);
370 for (String coId : list2) {
371 for (ActivityOfferingInfo ao : this.coService.getActivityOfferingsByCourseOffering(coId, context)) {
372
373
374 list.add(ao.getId());
375
376 }
377 }
378 return list;
379 }
380
381 @Override
382 public List<String> getUnscheduledActivityOfferingIdsBySoc(String socId, ContextInfo context)
383 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
384 PermissionDeniedException {
385 List<String> list = new ArrayList<String>();
386 List<String> list2 = this.getCourseOfferingIdsBySoc(socId, context);
387 for (String coId : list2) {
388 for (ActivityOfferingInfo ao : this.coService.getActivityOfferingsByCourseOffering(coId, context)) {
389
390
391 list.add(ao.getId());
392
393 }
394 }
395 return list;
396 }
397 }