View Javadoc

1   /**
2    * Copyright 2012 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   *
15   * Created by vgadiyak on 5/29/12
16   */
17  package org.kuali.student.enrollment.class2.courseoffering.rule;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.core.api.criteria.PredicateFactory;
21  import org.kuali.rice.core.api.criteria.QueryByCriteria;
22  import org.kuali.rice.kim.api.identity.Person;
23  import org.kuali.rice.krad.maintenance.MaintenanceDocument;
24  import org.kuali.rice.krad.util.GlobalVariables;
25  import org.kuali.student.common.uif.rule.KsMaintenanceDocumentRuleBase;
26  import org.kuali.student.enrollment.class2.courseoffering.dto.CourseOfferingCreateWrapper;
27  import org.kuali.student.enrollment.class2.courseoffering.dto.CourseOfferingEditWrapper;
28  import org.kuali.student.enrollment.class2.courseoffering.dto.OfferingInstructorWrapper;
29  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingConstants;
30  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingResourceLoader;
31  import org.kuali.student.enrollment.class2.courseoffering.util.CourseOfferingViewHelperUtil;
32  import org.kuali.student.enrollment.courseoffering.dto.CourseOfferingInfo;
33  import org.kuali.student.enrollment.courseoffering.dto.OfferingInstructorInfo;
34  import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
35  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
36  import org.kuali.student.r2.common.exceptions.MissingParameterException;
37  import org.kuali.student.r2.common.exceptions.OperationFailedException;
38  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
39  import org.kuali.student.r2.common.util.ContextUtils;
40  
41  import java.util.ArrayList;
42  import java.util.List;
43  
44  /**
45   * This class //TODO ...
46   *
47   * @author Kuali Student Team
48   */
49  public class CourseOfferingEditRule extends KsMaintenanceDocumentRuleBase {
50  
51      private CourseOfferingService courseOfferingService;
52  
53      @Override
54      protected boolean isDocumentValidForSave(MaintenanceDocument document) {
55          boolean valid = super.isDocumentValidForSave(document);
56  
57          if (document.getNewMaintainableObject().getDataObject() instanceof CourseOfferingEditWrapper){
58              CourseOfferingEditWrapper newCOWrapper = (CourseOfferingEditWrapper)document.getNewMaintainableObject().getDataObject();
59              CourseOfferingEditWrapper oldCOWrapper = (CourseOfferingEditWrapper)document.getOldMaintainableObject().getDataObject();
60  
61              // Only perform validateDuplicateSuffix check when CO code suffix part is changed, the code itself is readOnly and can't be modified at all.
62              // also notice a problem: the suffix of a CO from OldMaintainableObject (the DB reference dataset) could be null
63              // while even we didn't modify suffix in edit CO page, the suffix value in NewMaintainableObject became an empty string
64              if(newCOWrapper.getCreateCO()) {  // for Create CO page
65                  valid = validateRequiredFields(newCOWrapper);
66  
67                  if (valid) {
68                      valid = validateDuplicateSuffixCreate(newCOWrapper);
69                  }
70              } else { // for Edit CO page
71                  String newSuffix = newCOWrapper.getCourseOfferingInfo().getCourseNumberSuffix();
72                  String oldSuffix = oldCOWrapper.getCourseOfferingInfo().getCourseNumberSuffix();
73                  if ((oldSuffix == null || oldSuffix.isEmpty()) &&
74                      (newSuffix == null || newSuffix.isEmpty())) {
75                      // no change to valid
76                  }
77                  else if ((newSuffix != null) && !newSuffix.equals(oldSuffix) ) {
78                      valid &= validateDuplicateSuffix(newCOWrapper);
79                  }
80  
81                  // if no duplicate suffix then we validate the personnel ID
82                  if(valid) {
83                      valid = validatePersonnel(newCOWrapper);
84                  }
85              }
86          }
87  
88          return valid;
89      }
90  
91  
92      protected boolean validateDuplicateSuffix(CourseOfferingEditWrapper coWrapper){
93          // Catalog course code is case INSENSITIVE, but the suffix is case SENSITIVE
94          String courseCode = coWrapper.getCourse().getCode().toUpperCase();
95          String newCoCode = courseCode + coWrapper.getCourseOfferingInfo().getCourseNumberSuffix();
96  
97          try {
98              List<CourseOfferingInfo> wrapperList = getCourseOfferingService().getCourseOfferingsByCourseAndTerm(coWrapper.getCourse().getId(), coWrapper.getCourseOfferingInfo().getTermId(), ContextUtils.createDefaultContextInfo());
99              for (CourseOfferingInfo courseOfferingInfo : wrapperList) {
100 
101                 if (StringUtils.equals(newCoCode, courseOfferingInfo.getCourseOfferingCode())) {
102                     GlobalVariables.getMessageMap().putError(
103                             "document.newMaintainableObject.dataObject.courseOfferingInfo.courseNumberSuffix",
104                             CourseOfferingConstants.COURSEOFFERING_ERROR_CREATE_DUPLICATECODE, newCoCode, courseCode);
105                     return false;
106                 }
107             }
108         } catch (Exception e) {
109             throw new RuntimeException(e);
110         }
111 
112         return true;
113     }
114 
115 
116     protected boolean validatePersonnel(CourseOfferingEditWrapper coWrapper) {
117         List<OfferingInstructorWrapper> instructors = coWrapper.getInstructors();
118         boolean noError = true;
119         if (instructors != null && !instructors.isEmpty()) {
120             for (OfferingInstructorWrapper instructorWrapper : instructors)   {
121                 if (instructorWrapper != null) {
122                     OfferingInstructorInfo info = instructorWrapper.getOfferingInstructorInfo();
123                     if ((info != null) && (info.getPersonId() != null) && !info.getPersonId().isEmpty()) {
124                         // verify this is a legal personId
125                         List<Person> personList = CourseOfferingViewHelperUtil.getInstructorByPersonId(info.getPersonId());
126                         if (personList.isEmpty()) {
127                             GlobalVariables.getMessageMap().putErrorForSectionId(
128                                     "KS-CourseOfferingEdit-PersonnelSection",
129                                     CourseOfferingConstants.COURSEOFFERING_ERROR_INVALID_PERSONNEL_ID, info.getPersonId());
130                             noError &= false;
131                         } else {
132                             String instructorName = personList.get(0).getName().trim();
133                             if(instructorName != null && !instructorName.isEmpty()) {
134                                 if(!instructorName.equals(info.getPersonName())) {
135                                     GlobalVariables.getMessageMap().putErrorForSectionId(
136                                             "KS-CourseOfferingEdit-PersonnelSection",
137                                             CourseOfferingConstants.COURSEOFFERING_ERROR_UNMATCHING_PERSONNEL_NAME, info.getPersonName(), instructorName);
138                                     noError &=  false;
139                                 }
140                             }
141                             if(info.getTypeKey() == null || info.getTypeKey().isEmpty()) {
142                                 GlobalVariables.getMessageMap().putErrorForSectionId(
143                                         "KS-CourseOfferingEdit-PersonnelSection",
144                                         CourseOfferingConstants.COURSEOFFERING_ERROR_PERSONNEL_AFFILIATION);
145                                 noError &= false;
146                             }
147                         }
148                     }
149                 }
150             }
151         }
152 
153         return noError;
154     }
155 
156     protected boolean validateRequiredFields(CourseOfferingEditWrapper coWrapper){
157         if (coWrapper.getFormatOfferingList().isEmpty()){
158             GlobalVariables.getMessageMap().putErrorForSectionId("KS-CourseOfferingEdit-DeliveryFormats", CourseOfferingConstants.DELIVERY_FORMAT_REQUIRED_ERROR);
159             return false;
160         }
161         return true;
162     }
163 
164     protected boolean validateDuplicateSuffixCreate(CourseOfferingEditWrapper coWrapper){
165         String courseCode = coWrapper.getCourse().getCode().toUpperCase();
166         String newCoCode = courseCode + coWrapper.getCourseOfferingInfo().getCourseNumberSuffix().toUpperCase();
167         try {
168             List<CourseOfferingInfo> wrapperList =
169                     _findCourseOfferingsByTermAndCourseCode(coWrapper.getTerm().getId(), newCoCode);
170             for (CourseOfferingInfo courseOfferingInfo : wrapperList) {
171                 if (StringUtils.equals(newCoCode, courseOfferingInfo.getCourseOfferingCode())) {
172                     GlobalVariables.getMessageMap().putError(
173                             "document.newMaintainableObject.dataObject.courseOfferingInfo.courseNumberSuffix",
174                             CourseOfferingConstants.COURSEOFFERING_ERROR_CREATE_DUPLICATECODE, newCoCode, courseCode);
175                     return false;
176                 }
177             }
178         } catch (Exception e) {
179             throw new RuntimeException(e);
180         }
181 
182         return true;
183     }
184 
185     private List<CourseOfferingInfo> _findCourseOfferingsByTermAndCourseCode(String termId, String courseCode)
186             throws InvalidParameterException, MissingParameterException, PermissionDeniedException, OperationFailedException {
187         List<CourseOfferingInfo> courseOfferings = new ArrayList<CourseOfferingInfo>();
188         if (StringUtils.isNotBlank(courseCode) && StringUtils.isNotBlank(termId)) {
189             QueryByCriteria.Builder qbcBuilder = QueryByCriteria.Builder.create();
190             qbcBuilder.setPredicates(PredicateFactory.and(
191                     PredicateFactory.equal("courseOfferingCode", courseCode),
192                     PredicateFactory.equalIgnoreCase("atpId", termId)));
193             QueryByCriteria criteria = qbcBuilder.build();
194 
195             courseOfferings = getCourseOfferingService().searchForCourseOfferings(criteria, ContextUtils.createDefaultContextInfo());
196         }
197         return courseOfferings;
198     }
199 
200     protected CourseOfferingService getCourseOfferingService() {
201         if (courseOfferingService == null) {
202             courseOfferingService = CourseOfferingResourceLoader.loadCourseOfferingService();
203         }
204         return courseOfferingService;
205     }
206 }