Coverage Report - org.kuali.student.enrollment.class2.courseoffering.service.decorators.CourseOfferingServiceCalculationDecorator
 
Classes in this File Line Coverage Branch Coverage Complexity
CourseOfferingServiceCalculationDecorator
0%
0/105
0%
0/52
5.4
 
 1  
 /*
 2  
  * To change this template, choose Tools | Templates
 3  
  * and open the template in the editor.
 4  
  */
 5  
 package org.kuali.student.enrollment.class2.courseoffering.service.decorators;
 6  
 
 7  
 import java.util.ArrayList;
 8  
 import java.util.Arrays;
 9  
 import java.util.Collections;
 10  
 import java.util.List;
 11  
 import org.kuali.student.enrollment.acal.service.AcademicCalendarService;
 12  
 import org.kuali.student.enrollment.class2.courseoffering.service.transformer.CourseOfferingTransformer;
 13  
 import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
 14  
 import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
 15  
 import org.kuali.student.enrollment.courseoffering.dto.FormatOfferingInfo;
 16  
 import org.kuali.student.enrollment.courseoffering.dto.OfferingInstructorInfo;
 17  
 import org.kuali.student.lum.course.dto.CourseInfo;
 18  
 import org.kuali.student.lum.course.service.CourseService;
 19  
 import org.kuali.student.r2.common.dto.AttributeInfo;
 20  
 import org.kuali.student.r2.common.dto.ContextInfo;
 21  
 import org.kuali.student.r2.common.dto.ValidationResultInfo;
 22  
 import org.kuali.student.r2.common.exceptions.AlreadyExistsException;
 23  
 import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
 24  
 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
 25  
 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
 26  
 import org.kuali.student.r2.common.exceptions.MissingParameterException;
 27  
 import org.kuali.student.r2.common.exceptions.OperationFailedException;
 28  
 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
 29  
 import org.kuali.student.r2.common.exceptions.ReadOnlyException;
 30  
 import org.kuali.student.r2.common.exceptions.VersionMismatchException;
 31  
 import org.kuali.student.r2.common.infc.ValidationResult.ErrorLevel;
 32  
 import org.kuali.student.r2.common.util.constants.CourseOfferingSetServiceConstants;
 33  
 import org.springframework.transaction.annotation.Transactional;
 34  
 
 35  
 /**
 36  
  *
 37  
  * @author nwright
 38  
  */
 39  
 @Transactional(readOnly = true, noRollbackFor = {DoesNotExistException.class}, rollbackFor = {Throwable.class})
 40  0
 public class CourseOfferingServiceCalculationDecorator extends CourseOfferingServiceDecorator {
 41  
 
 42  
     private CourseService courseService;
 43  
     private AcademicCalendarService acalService;
 44  
 
 45  
     public AcademicCalendarService getAcalService() {
 46  0
         return acalService;
 47  
     }
 48  
 
 49  
     public void setAcalService(AcademicCalendarService acalService) {
 50  0
         this.acalService = acalService;
 51  0
     }
 52  
 
 53  
     public CourseService getCourseService() {
 54  0
         return courseService;
 55  
     }
 56  
 
 57  
     public void setCourseService(CourseService courseService) {
 58  0
         this.courseService = courseService;
 59  0
     }
 60  
 
 61  
     @Override
 62  
     @Transactional(readOnly = false)
 63  
     public CourseOfferingInfo rolloverCourseOffering(String sourceCoId,
 64  
             String targetTermId,
 65  
             List<String> optionKeys,
 66  
             ContextInfo context) throws AlreadyExistsException,
 67  
             DataValidationErrorException, DoesNotExistException, DataValidationErrorException, InvalidParameterException,
 68  
             MissingParameterException, OperationFailedException, PermissionDeniedException, ReadOnlyException {
 69  
 
 70  0
         CourseOfferingInfo sourceCo = this.getCourseOffering(sourceCoId, context);
 71  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.IGNORE_CANCELLED_OPTION_KEY)) {
 72  0
             throw new DataValidationErrorException("Skipped because course offering was cancelled in source term");
 73  
         }
 74  0
         CourseInfo sourceCourse = new R1CourseServiceHelper(courseService, acalService).getCourse(sourceCo.getCourseId());
 75  0
         List<CourseInfo> targetCourses = new R1CourseServiceHelper(courseService, acalService).getCoursesForTerm(
 76  
                 sourceCourse.getId(), targetTermId, context);
 77  0
         if (targetCourses.isEmpty()) {
 78  0
             throw new InvalidParameterException("Skipped because there is no valid version of the course in the target term");
 79  
         }
 80  0
         if (targetCourses.size() > 1) {
 81  0
             throw new InvalidParameterException(
 82  
                     "Skipped because there are more than one valid versions of the course in the target term");
 83  
         }
 84  0
         CourseInfo targetCourse = targetCourses.get(0);
 85  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.SKIP_IF_ALREADY_EXISTS_OPTION_KEY)) {
 86  0
             String existingCoId = this.findFirstExistingCourseOfferingIdInTargetTerm(targetCourse.getId(), targetTermId, context);
 87  0
             if (existingCoId != null) {
 88  0
                 throw new AlreadyExistsException("Skipped because course offering already exists in target term");
 89  
             }
 90  
         }
 91  
 
 92  
         // TODO: Not hard code "Active" but use a constant ... except these are R1 States
 93  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.STILL_OFFERABLE_OPTION_KEY)) {
 94  0
             if (!targetCourse.getState().equals("Active")) {
 95  0
                 throw new DataValidationErrorException("skipped because canonical course is no longer active");
 96  
             }
 97  
         }
 98  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.IF_NO_NEW_VERSION_OPTION_KEY)) {
 99  0
             if (!sourceCourse.getId().equals(targetCourse.getId())) {
 100  0
                 throw new DataValidationErrorException("skipped because there is a new version of the canonical course");
 101  
             }
 102  
         }
 103  0
         CourseOfferingInfo targetCo = new CourseOfferingInfo(sourceCo);
 104  0
         targetCo.setId(null);
 105  
         // clear out the ids on the internal sub-objects too
 106  0
         for (OfferingInstructorInfo instr : targetCo.getInstructors()) {
 107  0
             instr.setId(null);
 108  
         }
 109  
 //        for (RevenueInfo rev : targetCo.getRevenues()) {
 110  
 //            rev.setId(null);
 111  
 //        }
 112  
 //        for (FeeInfo fee : targetCo.getFees()) {
 113  
 //            fee.setId(null);
 114  
 //        }
 115  0
         for (AttributeInfo attr : targetCo.getAttributes()) {
 116  0
             attr.setId(null);
 117  
         }
 118  0
         targetCo.setTermId(targetTermId);
 119  0
         targetCo.setMeta(null);
 120  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.NO_INSTRUCTORS_OPTION_KEY)) {
 121  0
             targetCo.getInstructors().clear();
 122  
         }
 123  0
         targetCo.setCourseId(targetCourse.getId());
 124  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.USE_CANNONICAL_OPTION_KEY)) {
 125  
             // copy from cannonical
 126  0
             CourseOfferingTransformer coTransformer = new CourseOfferingTransformer();
 127  0
             coTransformer.copyFromCanonical(targetCourse, targetCo, optionKeys);
 128  
         }
 129  0
         targetCo = this.createCourseOffering(targetCo.getCourseId(), targetCo.getTermId(), targetCo.getTypeKey(),
 130  
                 targetCo, optionKeys, context);
 131  0
         for (FormatOfferingInfo sourceFo : this.getFormatOfferingsByCourseOffering(sourceCo.getId(), context)) {
 132  0
             FormatOfferingInfo targetFo = new FormatOfferingInfo(sourceFo);
 133  0
             targetFo.setId(null);
 134  
             // clear out the ids on the internal sub-objects
 135  0
             for (AttributeInfo attr : targetFo.getAttributes()) {
 136  0
                 attr.setId(null);
 137  
             }
 138  0
             targetFo.setCourseOfferingId(targetCo.getId());
 139  0
             targetFo.setTermId(targetTermId);
 140  0
             targetFo.setMeta(null);
 141  0
             targetFo = this.createFormatOffering(targetFo.getCourseOfferingId(), targetFo.getFormatId(),
 142  
                     targetFo.getTypeKey(), targetFo, context);
 143  0
             for (ActivityOfferingInfo sourceAo : this.getActivityOfferingsByFormatOffering(sourceFo.getId(), context)) {
 144  0
                 ActivityOfferingInfo targetAo = new ActivityOfferingInfo(sourceAo);
 145  0
                 targetAo.setId(null);
 146  
                 // clear out the ids on the internal sub-objects
 147  0
                 for (AttributeInfo attr : targetAo.getAttributes()) {
 148  0
                     attr.setId(null);
 149  
                 }
 150  0
                 for (OfferingInstructorInfo instr : targetAo.getInstructors()) {
 151  0
                     instr.setId(null);
 152  
                 }
 153  0
                 targetAo.setFormatOfferingId(targetFo.getId());
 154  0
                 targetAo.setTermId(targetTermId);
 155  0
                 targetAo.setMeta(null);
 156  0
                 if (optionKeys.contains(CourseOfferingSetServiceConstants.NO_SCHEDULE_OPTION_KEY)) {
 157  0
                     targetAo.setScheduleId(null);
 158  
                     // TODO: set the schedule request to null as well
 159  
                 }
 160  0
                 if (optionKeys.contains(CourseOfferingSetServiceConstants.NO_INSTRUCTORS_OPTION_KEY)) {
 161  0
                     targetAo.getInstructors().clear();
 162  
                 }
 163  0
                 targetAo = this.createActivityOffering(targetAo.getFormatOfferingId(), targetAo.getActivityId(),
 164  
                         targetAo.getTypeKey(), targetAo, context);
 165  0
             }
 166  0
         }
 167  0
         return targetCo;
 168  
     }
 169  
     
 170  
     @Override
 171  
     @Transactional(readOnly = false)
 172  
     public CourseOfferingInfo updateCourseOfferingFromCanonical(String courseOfferingId, List<String> optionKeys, ContextInfo context)
 173  
             throws DataValidationErrorException,
 174  
             DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException,
 175  
             PermissionDeniedException, VersionMismatchException {
 176  0
         CourseOfferingInfo co = this.getCourseOffering(courseOfferingId, context);
 177  0
         CourseInfo course = new R1CourseServiceHelper(courseService, acalService).getCourse(co.getCourseId());
 178  
         // copy from cannonical
 179  0
         CourseOfferingTransformer coTransformer = new CourseOfferingTransformer();
 180  0
         coTransformer.copyFromCanonical(course, co, optionKeys);
 181  
         try {
 182  0
             return this.updateCourseOffering(courseOfferingId, co, context);
 183  0
         } catch (ReadOnlyException ex) {
 184  0
             throw new OperationFailedException("unexpected", ex);
 185  
         }
 186  
         // TODO: continue traversing down the formats and activities updating from the canonical
 187  
     }
 188  
 
 189  
     @Override
 190  
     public List<ValidationResultInfo> validateCourseOfferingFromCanonical(CourseOfferingInfo courseOfferingInfo,
 191  
             List<String> optionKeys, ContextInfo context) throws DoesNotExistException,
 192  
             InvalidParameterException, MissingParameterException, OperationFailedException {
 193  0
         List<ValidationResultInfo> results = new ArrayList<ValidationResultInfo>();
 194  0
         CourseInfo course = new R1CourseServiceHelper(courseService, acalService).getCourse(courseOfferingInfo.getCourseId());
 195  0
         if (!optionKeys.contains(CourseOfferingSetServiceConstants.NOT_COURSE_TITLE_OPTION_KEY)) {
 196  0
             results.addAll(this.compare("CourseTitle", course.getCourseTitle(), courseOfferingInfo.getCourseOfferingTitle(), null));
 197  
         }
 198  0
         results.addAll(this.compare("Code", course.getCode(), courseOfferingInfo.getCourseOfferingCode(), null));
 199  
 
 200  0
         if (optionKeys.contains(CourseOfferingSetServiceConstants.CREDITS_MATCH_SCHEDULED_HOURS_OPTION_KEY)) {
 201  0
             results.addAll(compareCreditsToSchedule(course, courseOfferingInfo));
 202  
         }
 203  0
         return results;
 204  
     }
 205  
 
 206  
     private List<ValidationResultInfo> compare(String element, String courseValue, String coValue, String message) {
 207  0
         if (courseValue == null && coValue == null) {
 208  0
             return Collections.EMPTY_LIST;
 209  
         }
 210  0
         if (courseValue.equals(coValue)) {
 211  0
             return Collections.EMPTY_LIST;
 212  
         }
 213  0
         ValidationResultInfo result = new ValidationResultInfo();
 214  0
         result.setElement(element);
 215  0
         result.setLevel(ErrorLevel.ERROR);
 216  0
         result.setMessage(message);
 217  0
         return Arrays.asList(result);
 218  
     }
 219  
 
 220  
     protected List<ValidationResultInfo> compareCreditsToSchedule(CourseInfo course, CourseOfferingInfo co) {
 221  
         // TODO: implement this complex logic
 222  
 
 223  0
         return Collections.EMPTY_LIST;
 224  
     }
 225  
 
 226  
     private String findFirstExistingCourseOfferingIdInTargetTerm(String targetCourseId, String targetTermId, ContextInfo context)
 227  
             throws DoesNotExistException, OperationFailedException {
 228  
         List<CourseOfferingInfo> list;
 229  
         try {
 230  0
             list = this.getCourseOfferingsByCourseAndTerm(targetCourseId, targetTermId, context);
 231  0
         } catch (InvalidParameterException ex) {
 232  0
             throw new OperationFailedException("unexpected", ex);
 233  0
         } catch (MissingParameterException ex) {
 234  0
             throw new OperationFailedException("unexpected", ex);
 235  0
         } catch (PermissionDeniedException ex) {
 236  0
             throw new OperationFailedException("unexpected", ex);
 237  0
         }
 238  0
         if (list.isEmpty()) {
 239  0
             return null;
 240  
         }
 241  0
         return list.get(0).getId();
 242  
     }
 243  
 }