1 package org.kuali.student.lum.lu.ui.course.server.gwt;
2
3 import java.util.List;
4
5 import org.apache.commons.beanutils.PropertyUtils;
6 import org.apache.log4j.Logger;
7 import org.kuali.student.common.assembly.data.Data;
8 import org.kuali.student.common.dto.CurrencyAmountInfo;
9 import org.kuali.student.common.dto.DtoConstants;
10 import org.kuali.student.common.exceptions.AlreadyExistsException;
11 import org.kuali.student.common.exceptions.CircularRelationshipException;
12 import org.kuali.student.common.exceptions.DataValidationErrorException;
13 import org.kuali.student.common.exceptions.DependentObjectsExistException;
14 import org.kuali.student.common.exceptions.DoesNotExistException;
15 import org.kuali.student.common.exceptions.InvalidParameterException;
16 import org.kuali.student.common.exceptions.MissingParameterException;
17 import org.kuali.student.common.exceptions.OperationFailedException;
18 import org.kuali.student.common.exceptions.PermissionDeniedException;
19 import org.kuali.student.common.exceptions.UnsupportedActionException;
20 import org.kuali.student.common.exceptions.VersionMismatchException;
21 import org.kuali.student.common.ui.client.service.DataSaveResult;
22 import org.kuali.student.common.ui.server.gwt.DataService;
23 import org.kuali.student.core.proposal.dto.ProposalInfo;
24 import org.kuali.student.core.proposal.service.ProposalService;
25 import org.kuali.student.core.statement.dto.ReqCompFieldInfo;
26 import org.kuali.student.core.statement.dto.ReqComponentInfo;
27 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
28 import org.kuali.student.core.statement.service.StatementService;
29 import org.kuali.student.lum.course.dto.ActivityInfo;
30 import org.kuali.student.lum.course.dto.CourseCrossListingInfo;
31 import org.kuali.student.lum.course.dto.CourseFeeInfo;
32 import org.kuali.student.lum.course.dto.CourseInfo;
33 import org.kuali.student.lum.course.dto.CourseJointInfo;
34 import org.kuali.student.lum.course.dto.CourseRevenueInfo;
35 import org.kuali.student.lum.course.dto.CourseVariationInfo;
36 import org.kuali.student.lum.course.dto.FormatInfo;
37 import org.kuali.student.lum.course.dto.LoDisplayInfo;
38 import org.kuali.student.lum.course.service.CourseService;
39 import org.kuali.student.lum.lrc.dto.ResultComponentInfo;
40 import org.kuali.student.lum.lu.LUConstants;
41 import org.kuali.student.lum.lu.dto.AffiliatedOrgInfo;
42 import org.kuali.student.lum.lu.dto.CluSetInfo;
43 import org.kuali.student.lum.lu.service.LuService;
44 import org.kuali.student.lum.statement.typekey.ReqComponentFieldTypes;
45 import org.springframework.transaction.annotation.Transactional;
46 @Transactional(noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
47 public class CopyCourseServiceImpl {
48 final static Logger LOG = Logger.getLogger(CopyCourseServiceImpl.class);
49
50 private DataService courseDataService;
51 private DataService courseProposalDataService;
52 private CourseService courseService;
53 private LuService luService;
54 private StatementService statementService;
55 private ProposalService proposalService;
56
57 private String defaultDocumentType=LUConstants.PROPOSAL_TYPE_COURSE_CREATE;
58 private String defaultState=DtoConstants.STATE_DRAFT;
59
60 private List<String> ignoreProperties;
61
62 public DataSaveResult createCopyCourse(String originalCluId) throws Exception {
63
64 CourseInfo copiedCourse = copyCourse(originalCluId);
65
66 DataSaveResult result = new DataSaveResult();
67 result.setValue(courseDataService.getData(copiedCourse.getId()));
68 return result;
69 }
70
71 public DataSaveResult createCopyCourseProposal(String originalProposalId) throws Exception {
72
73 ProposalInfo copiedProposal = copyProposal(originalProposalId);
74
75
76 Data data = courseProposalDataService.getData(copiedProposal.getId());
77
78
79 return courseProposalDataService.saveData(data);
80 }
81
82 private CourseInfo copyCourse(String originalCluId) throws Exception{
83
84 return copyCourse(originalCluId, null, defaultState, ignoreProperties, statementService, luService, courseService);
85 }
86 private ProposalInfo copyProposal(String originalProposalId) throws Exception{
87 try {
88
89 ProposalInfo originalProposal = proposalService.getProposal(originalProposalId);
90
91
92 String originalCluId = originalProposal.getProposalReference().get(0);
93 CourseInfo copiedCourse = copyCourse(originalCluId);
94
95
96 originalProposal.setId(null);
97 originalProposal.setWorkflowId(null);
98 originalProposal.setState(defaultState);
99 originalProposal.setType(defaultDocumentType);
100 originalProposal.getProposalReference().set(0, copiedCourse.getId());
101 originalProposal.getProposerOrg().clear();
102 originalProposal.getProposerPerson().clear();
103 originalProposal.setName(null);
104
105
106 ProposalInfo copiedProposal = proposalService.createProposal(defaultDocumentType, originalProposal);
107
108 return copiedProposal;
109
110 } catch (Exception e) {
111 LOG.error("Error copying proposal id:" + originalProposalId, e);
112 throw e;
113 }
114 }
115
116 private void resetIds(CourseInfo course) {
117
118 for(CourseJointInfo joint:course.getJoints()){
119 joint.setRelationId(null);
120 }
121
122 for(LoDisplayInfo lo:course.getCourseSpecificLOs()){
123 resetLoRecursively(lo);
124 }
125
126 for(FormatInfo format:course.getFormats()){
127 format.setId(null);
128 for(ActivityInfo activity:format.getActivities()){
129 activity.setId(null);
130 }
131 }
132
133 for(ResultComponentInfo result:course.getCreditOptions()){
134 result.setId(null);
135 }
136
137 for(CourseCrossListingInfo crossListing:course.getCrossListings()){
138 crossListing.setId(null);
139 }
140
141 for(AffiliatedOrgInfo orgInfo:course.getExpenditure().getAffiliatedOrgs()){
142 orgInfo.setId(null);
143 }
144
145 for(CourseFeeInfo fee:course.getFees()){
146 fee.setId(null);
147 for(CurrencyAmountInfo feeAmount:fee.getFeeAmounts()){
148 feeAmount.setId(null);
149 }
150 }
151
152 for(CourseRevenueInfo revenue:course.getRevenues()){
153 revenue.setId(null);
154 for(AffiliatedOrgInfo orgInfo:revenue.getAffiliatedOrgs()){
155 orgInfo.setId(null);
156 }
157 }
158
159 for(CourseVariationInfo variation:course.getVariations()){
160 variation.setId(null);
161 }
162 }
163
164 private void resetLoRecursively(LoDisplayInfo lo){
165
166 lo.getLoInfo().setId(null);
167 for(LoDisplayInfo nestedLo:lo.getLoDisplayInfoList()){
168 resetLoRecursively(nestedLo);
169 }
170 }
171
172 private void clearStatementTreeViewIds(
173 List<StatementTreeViewInfo> statementTreeViews, String newState, LuService luService) throws OperationFailedException {
174
175 for(StatementTreeViewInfo statementTreeView:statementTreeViews){
176 clearStatementTreeViewIdsRecursively(statementTreeView, newState, luService);
177 }
178 }
179
180
181
182
183
184
185
186 private void clearStatementTreeViewIdsRecursively(StatementTreeViewInfo statementTreeView, String newState,LuService luService) throws OperationFailedException{
187 statementTreeView.setId(null);
188 statementTreeView.setState(newState);
189
190
191 for(ReqComponentInfo reqComp:statementTreeView.getReqComponents()){
192 reqComp.setId(null);
193 reqComp.setState(newState);
194 for(ReqCompFieldInfo field:reqComp.getReqCompFields()){
195 field.setId(null);
196
197 if(ReqComponentFieldTypes.COURSE_CLUSET_KEY.getId().equals(field.getType())||
198 ReqComponentFieldTypes.PROGRAM_CLUSET_KEY.getId().equals(field.getType())||
199 ReqComponentFieldTypes.CLUSET_KEY.getId().equals(field.getType())){
200 try {
201 CluSetInfo cluSet = luService.getCluSetInfo(field.getValue());
202 cluSet.setId(null);
203 cluSet.setState(newState);
204
205 if (cluSet.getMembershipQuery() != null){
206 cluSet.getCluIds().clear();
207 cluSet.getCluSetIds().clear();
208 }
209 cluSet = luService.createCluSet(cluSet.getType(), cluSet);
210 field.setValue(cluSet.getId());
211 } catch (Exception e) {
212 throw new OperationFailedException("Error copying clusets.", e);
213 }
214 }
215
216 }
217 }
218
219 for(StatementTreeViewInfo child: statementTreeView.getStatements()){
220 clearStatementTreeViewIdsRecursively(child,newState,luService);
221 }
222 }
223
224 private void copyStatements(String originalCluId, String newCluId, String newState,
225 StatementService statementService, LuService luService, CourseService courseService) throws OperationFailedException, DoesNotExistException, InvalidParameterException, MissingParameterException, PermissionDeniedException, DataValidationErrorException {
226
227 List<StatementTreeViewInfo> statementTreeViews = courseService.getCourseStatements(originalCluId,null,null);
228
229
230 if(statementTreeViews!=null){
231 clearStatementTreeViewIds(statementTreeViews,newState,luService);
232
233 for(StatementTreeViewInfo statementTreeView:statementTreeViews){
234 courseService.createCourseStatement(newCluId, statementTreeView);
235 }
236 }
237 }
238
239 private CourseInfo copyCourse(String originalCluId, String newCluId, String newState, List<String> ignoreProperties, StatementService statementService, LuService luService, CourseService courseService) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, AlreadyExistsException, DataValidationErrorException, VersionMismatchException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException{
240 CourseInfo originalCourse = courseService.getCourse(originalCluId);
241 resetIds(originalCourse);
242 originalCourse.setCourseTitle("Copy of "+originalCourse.getCourseTitle());
243
244
245 if(newState==null){
246 newState = originalCourse.getState();
247 }
248
249 originalCourse.setId(newCluId);
250 originalCourse.setState(newState);
251 originalCourse.setPilotCourse(false);
252
253
254 if(ignoreProperties!=null){
255 for(String property:ignoreProperties){
256 try {
257 PropertyUtils.setProperty(originalCourse, property, null);
258 } catch (Exception e) {
259 throw new InvalidParameterException("Ignore property is invalid and is causing an exception.",e);
260 }
261 }
262 }
263
264 CourseInfo newCourse = courseService.createCourse(originalCourse);
265 copyStatements(originalCluId, newCourse.getId(), newState, statementService, luService, courseService);
266 return newCourse;
267 }
268
269 public void setCourseService(CourseService courseService) {
270 this.courseService = courseService;
271 }
272
273 public void setLuService(LuService luService) {
274 this.luService = luService;
275 }
276
277 public void setStatementService(StatementService statementService) {
278 this.statementService = statementService;
279 }
280
281 public void setProposalService(ProposalService proposalService) {
282 this.proposalService = proposalService;
283 }
284
285 public void setCourseDataService(DataService courseDataService) {
286 this.courseDataService = courseDataService;
287 }
288
289 public void setCourseProposalDataService(DataService courseProposalDataService) {
290 this.courseProposalDataService = courseProposalDataService;
291 }
292
293 public void setDefaultDocumentType(String defaultDocumentType) {
294 this.defaultDocumentType = defaultDocumentType;
295 }
296
297 public void setDefaultState(String defaultState) {
298 this.defaultState = defaultState;
299 }
300
301 public void setIgnoreProperties(List<String> ignoreProperties) {
302 this.ignoreProperties = ignoreProperties;
303 }
304
305 }