1 package org.kuali.student.lum.workflow;
2
3 import java.util.Iterator;
4 import java.util.List;
5
6 import org.kuali.student.r2.common.dto.AttributeInfo;
7 import org.kuali.student.r2.common.dto.ContextInfo;
8 import org.kuali.student.r2.common.dto.DtoConstants;
9 import org.kuali.student.r2.common.dto.StatusInfo;
10 import org.kuali.student.r2.common.exceptions.CircularReferenceException;
11 import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
12 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
13 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
14 import org.kuali.student.r2.common.exceptions.MissingParameterException;
15 import org.kuali.student.r2.common.exceptions.OperationFailedException;
16 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
17 import org.kuali.student.r2.common.exceptions.VersionMismatchException;
18 import org.kuali.student.r2.core.versionmanagement.dto.VersionDisplayInfo;
19
20 import org.kuali.student.r1.lum.course.service.CourseServiceConstants;
21 import org.kuali.student.r1.core.statement.dto.StatementTreeViewInfo;
22
23 import org.kuali.student.r2.lum.course.dto.CourseInfo;
24 import org.kuali.student.r2.lum.course.service.CourseService;
25
26 import org.springframework.transaction.annotation.Transactional;
27
28 @Transactional(noRollbackFor = { DoesNotExistException.class }, rollbackFor = { Throwable.class })
29 public class CourseStateChangeServiceImpl {
30 private CourseService courseService;
31
32
33
34
35
36
37
38
39
40
41
42
43 public StatusInfo changeState(String courseId, String newState, String prevEndTermAtpId,ContextInfo contextInfo) throws Exception {
44
45
46
47 CourseInfo courseInfo = courseService.getCourse(courseId,contextInfo);
48
49
50
51
52
53 CourseInfo currVerCourse = getCurrentVersionOfCourse(courseInfo, contextInfo);
54
55
56
57 boolean isOnlyVersion = (courseInfo.getId().equals(currVerCourse.getId()));
58
59
60 StatusInfo ret = new StatusInfo();
61
62
63 if ((newState!=null) && (newState.equals(DtoConstants.STATE_ACTIVE))) {
64
65
66
67
68 if ((courseInfo!=null) && courseInfo.isPilotCourse()){
69
70
71
72 if (!isOnlyVersion){
73 currVerCourse.setStateKey(DtoConstants.STATE_SUPERSEDED);
74 courseService.updateCourse(currVerCourse.getId(), currVerCourse, contextInfo);
75 updateStatementTreeViewInfoState(currVerCourse, contextInfo);
76
77 }
78
79
80
81 courseInfo.getAttributes().add(new AttributeInfo("retirementRationale", "Pilot Course"));
82 courseInfo.getAttributes().add(new AttributeInfo("lastTermOffered", courseInfo.getEndTerm()));
83 courseInfo.setStateKey(DtoConstants.STATE_ACTIVE);
84 retireCourse(courseInfo, contextInfo);
85
86
87
88 if (!isOnlyVersion){
89
90
91
92 courseInfo = courseService.getCourse(courseId, contextInfo);
93
94
95 courseService.setCurrentCourseVersion(courseInfo.getId(),
96 null, contextInfo);
97
98 }
99
100 }else{
101
102 activateCourse(courseInfo, prevEndTermAtpId, contextInfo);
103 }
104 } else if (newState.equals(DtoConstants.STATE_RETIRED)) {
105
106 retireCourse(courseInfo, contextInfo);
107 }
108
109 ret.setSuccess(new Boolean(true));
110
111 return ret;
112 }
113
114
115
116
117
118
119
120 protected void activateCourse(CourseInfo courseToActivate, String prevEndTermAtpId,ContextInfo contextInfo) throws Exception{
121 CourseInfo currVerCourse = getCurrentVersionOfCourse(courseToActivate,contextInfo);
122 String existingState = courseToActivate.getStateKey();
123 String currVerState = currVerCourse.getStateKey();
124 boolean isCurrVer = (courseToActivate.getId().equals(currVerCourse.getId()));
125
126 if (existingState.equals(DtoConstants.STATE_DRAFT)) {
127
128 if (isCurrVer) {
129
130 updateCourseVersionStates(courseToActivate, DtoConstants.STATE_ACTIVE, currVerCourse, null, true, prevEndTermAtpId,contextInfo);
131 } else if (currVerState.equals(DtoConstants.STATE_ACTIVE) ||
132 currVerState.equals(DtoConstants.STATE_SUSPENDED) ||
133 currVerState.equals(DtoConstants.STATE_RETIRED)) {
134 updateCourseVersionStates(courseToActivate, DtoConstants.STATE_ACTIVE, currVerCourse, DtoConstants.STATE_SUPERSEDED, true, prevEndTermAtpId,contextInfo);
135 }
136 }
137 }
138
139
140
141
142
143
144 protected void retireCourse(CourseInfo courseToRetire,ContextInfo contextInfo) throws Exception{
145 String existingState = courseToRetire.getStateKey();
146
147 if (existingState.equals(DtoConstants.STATE_ACTIVE) || existingState.equals(DtoConstants.STATE_SUSPENDED)){
148 courseToRetire.setStateKey(DtoConstants.STATE_RETIRED);
149
150 courseService.updateCourse(courseToRetire.getId(),courseToRetire,contextInfo);
151 updateStatementTreeViewInfoState(courseToRetire,contextInfo);
152 }
153 }
154
155
156
157
158
159
160 protected CourseInfo getCurrentVersionOfCourse(CourseInfo course,ContextInfo contextInfo)
161 throws Exception {
162
163 String verIndId = course.getVersion().getVersionIndId();
164
165
166 VersionDisplayInfo curVerDisplayInfo = courseService.getCurrentVersion(
167 CourseServiceConstants.COURSE_NAMESPACE_URI, verIndId,contextInfo);
168 String curVerId = curVerDisplayInfo.getId();
169
170
171 CourseInfo currVerCourse = courseService.getCourse(curVerId,contextInfo);
172
173 return currVerCourse;
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 @Transactional(readOnly = false)
199 private void updateCourseVersionStates(CourseInfo thisVerCourse,
200 String thisVerNewState, CourseInfo currVerCourse,
201 String currVerNewState, boolean makeCurrent,
202 String prevEndTermAtpId,ContextInfo contextInfo) throws Exception {
203 String thisVerPrevState = thisVerCourse.getStateKey();
204
205
206
207 boolean isCurrent = thisVerCourse.getId().equals(currVerCourse.getId());
208 if(!makeCurrent || !isCurrent || !thisVerCourse.getVersion().getSequenceNumber().equals(1)){
209 makeCurrent &= !isCurrent;
210 }
211
212 if (thisVerNewState == null) {
213 throw new InvalidParameterException("new state cannot be null");
214 } else {
215 thisVerCourse.setStateKey(thisVerNewState);
216 courseService.updateCourse(thisVerCourse.getId(),thisVerCourse,contextInfo);
217 updateStatementTreeViewInfoState(thisVerCourse,contextInfo);
218 }
219
220
221 if (currVerNewState != null) {
222 currVerCourse.setStateKey(currVerNewState);
223 if(currVerCourse.getEndTerm()==null){
224 currVerCourse.setEndTerm(prevEndTermAtpId);
225 }
226 courseService.updateCourse(currVerCourse.getId(),currVerCourse,contextInfo);
227 updateStatementTreeViewInfoState(currVerCourse,contextInfo);
228 }
229
230 if (makeCurrent == true) {
231 courseService.setCurrentCourseVersion(thisVerCourse.getId(),
232 null,contextInfo);
233 }
234
235
236
237
238
239 if (thisVerPrevState.equals(DtoConstants.STATE_APPROVED)
240 && thisVerNewState.equals(DtoConstants.STATE_ACTIVE)) {
241
242 List<VersionDisplayInfo> versions = courseService.getVersions(
243 CourseServiceConstants.COURSE_NAMESPACE_URI, thisVerCourse
244 .getVersion().getVersionIndId(),contextInfo);
245 Long startSeq = new Long(1);
246
247 if (!isCurrent && (currVerCourse.getId() != thisVerCourse.getId())) {
248 startSeq = currVerCourse.getVersion().getSequenceNumber() + 1;
249 }
250
251 for (VersionDisplayInfo versionInfo : versions) {
252 if (versionInfo.getSequenceNumber() >= startSeq) {
253 CourseInfo otherCourse = courseService
254 .getCourse(versionInfo.getId(),contextInfo);
255 if (otherCourse.getStateKey().equals(
256 DtoConstants.STATE_APPROVED)
257 || otherCourse.getStateKey().equals(
258 DtoConstants.STATE_SUBMITTED)
259 || otherCourse.getStateKey().equals(
260 DtoConstants.STATE_DRAFT)) {
261 otherCourse.setStateKey(DtoConstants.STATE_SUPERSEDED);
262 courseService.updateCourse(otherCourse.getId(),otherCourse,contextInfo);
263 updateStatementTreeViewInfoState(otherCourse,contextInfo);
264 }
265 }
266 }
267 }
268
269 }
270
271 public void setCourseService(CourseService courseService) {
272 this.courseService = courseService;
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 public void updateStatementTreeViewInfoState(CourseInfo courseInfo,ContextInfo contextInfo)
294 throws DoesNotExistException, InvalidParameterException,
295 MissingParameterException, OperationFailedException,
296 PermissionDeniedException, DataValidationErrorException,
297 CircularReferenceException, VersionMismatchException {
298
299
300
301 List<StatementTreeViewInfo> statementTreeViewInfos = courseService
302 .getCourseStatements(courseInfo.getId(), null, null,contextInfo);
303
304 if(statementTreeViewInfos != null){
305
306 for (Iterator<StatementTreeViewInfo> it = statementTreeViewInfos.iterator(); it.hasNext();){
307 StatementUtil.updateStatementTreeViewInfoState(courseInfo.getStateKey(), it.next());
308 }
309
310
311
312 for (Iterator<StatementTreeViewInfo> it = statementTreeViewInfos.iterator(); it.hasNext();){
313 courseService.updateCourseStatement(courseInfo.getId(), null, it.next(), contextInfo);
314 }
315 }
316 }
317
318 }