View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.kpme.core.department.validation;
17  
18  import java.util.List;
19  import java.util.ListIterator;
20  
21  import org.apache.commons.lang.StringUtils;
22  import org.joda.time.LocalDate;
23  import org.kuali.kpme.core.department.Department;
24  import org.kuali.kpme.core.kfs.coa.businessobject.Chart;
25  import org.kuali.kpme.core.kfs.coa.businessobject.Organization;
26  import org.kuali.kpme.core.role.KPMERole;
27  import org.kuali.kpme.core.role.department.DepartmentPrincipalRoleMemberBo;
28  import org.kuali.kpme.core.service.HrServiceLocator;
29  import org.kuali.kpme.core.util.TKUtils;
30  import org.kuali.rice.kim.api.role.Role;
31  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
32  import org.kuali.rice.kim.impl.role.RoleMemberBo;
33  import org.kuali.rice.kns.document.MaintenanceDocument;
34  import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
35  import org.kuali.rice.krad.bo.PersistableBusinessObject;
36  import org.kuali.rice.krad.service.KRADServiceLocator;
37  
38  @SuppressWarnings("deprecation")
39  public class DepartmentValidation extends MaintenanceDocumentRuleBase {
40  
41  	@Override
42  	protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
43  		boolean valid = true;
44  
45  		PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo();
46  		
47  		if (pbo instanceof Department) {
48  			Department department = (Department) pbo;
49  			if(StringUtils.isBlank(department.getHrDeptId())) {
50  				// do not need to validate existing department when editing an existing department 
51  				valid &= validateDepartment(department);
52  			}
53  			valid &= validateChart(department.getChart());
54  			valid &= validateOrg(department.getOrg());
55  			valid &= validateChartAndOrg(department.getChart(), department.getOrg());
56  			valid &= validateRolePresent(department.getRoleMembers(), department.getEffectiveLocalDate());
57  		}
58  
59  		return valid;
60  	}
61  	
62  	protected boolean validateDepartment(Department department) {
63  		boolean valid = true;
64  		
65  		if (StringUtils.isNotBlank(department.getDept()) && department.getEffectiveDate() != null) {
66  			List<Department> depts = HrServiceLocator.getDepartmentService().getDepartments(department.getDept());
67  			if (depts != null && depts.size() > 0) {
68  				 this.putFieldError("dept", "error.department.duplicate.exists", department.getDept());
69  				 valid = false;
70  			}
71  		}
72  		
73  		return valid;
74  	}
75  
76  	protected boolean validateChart(String chart) {
77  		boolean valid = true;
78  		
79  		if (chart != null) {
80  			Chart chartObj = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Chart.class, chart);
81  
82  			if (chartObj == null) {
83  				this.putFieldError("chart", "dept.chart.notfound", chart);
84  				valid = false;
85  			}
86  		}
87  		
88  		return valid;
89  	}
90  
91  	protected boolean validateOrg(String organization) {
92  		boolean valid = true;
93  		
94  		if (organization != null) {
95  			Organization organizationObj = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Organization.class, organization);
96  
97  			if (organizationObj == null) {
98  				this.putFieldError("org", "dept.org.notfound", organization);
99  				valid = false;
100 			}
101 		}
102 		
103 		return valid;
104 	}
105 
106 	boolean validateChartAndOrg(String chart, String organization) {
107 		boolean valid = true;
108 		
109 		if (chart != null && organization != null) {
110 			Chart chartObj = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Chart.class, chart);
111 			Organization organizationObj = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Organization.class, organization);
112 			if (chartObj != null && organizationObj != null) {
113 				Chart organizationChart = organizationObj.getChartOfAccounts();
114 				if (!StringUtils.equals(chartObj.getChartOfAccountsCode(), organizationChart.getChartOfAccountsCode())) {
115 					String[] params = new String[] {organization, chart};
116 					this.putFieldError("org", "dept.org.chart.notmatch", params);
117 					valid = false;
118 				}
119 			}
120 		}
121 		
122 		return valid;
123 	}
124 
125 	boolean validateRolePresent(List<DepartmentPrincipalRoleMemberBo> roleMembers, LocalDate effectiveDate) {
126 		boolean valid = true;
127 		boolean activeFlag = false;
128 		
129 		for (ListIterator<DepartmentPrincipalRoleMemberBo> iterator = roleMembers.listIterator(); iterator.hasNext(); ) {
130 			int index = iterator.nextIndex();
131 			RoleMemberBo roleMember = iterator.next();
132 			Role role = KimApiServiceLocator.getRoleService().getRole(roleMember.getRoleId());
133 			activeFlag |= roleMember.isActive();
134 			
135 			String prefix = "roleMembers[" + index + "].";
136 			
137 			if (roleMember.getActiveToDateValue() != null) {
138 				if (effectiveDate.compareTo(roleMember.getActiveToDate().toLocalDate()) >= 0
139 						|| roleMember.getActiveFromDateValue().compareTo(roleMember.getActiveToDateValue()) >= 0) {
140 					this.putFieldError(prefix + "expirationDate", "error.role.expiration");
141 					valid = false;
142 				} 
143 			}
144 			if (StringUtils.equals(role.getName(), KPMERole.PAYROLL_PROCESSOR_DELEGATE.getRoleName())) {
145 				if(roleMember.getActiveToDateValue() == null) {
146 					this.putFieldError(prefix + "expirationDate", "error.role.expiration.required");
147 					valid = false;
148 				} else {
149 					LocalDate dateLimit = roleMember.getActiveFromDate().toLocalDate().plusMonths(6).minusDays(1);
150 					if(roleMember.getActiveToDate().toLocalDate().isAfter(dateLimit)) {
151 						this.putFieldError(prefix + "expirationDate", "error.role.expiration.duration");
152 						valid = false;
153 					}
154 				}
155 			}
156 				
157 		}
158 
159 		if (!activeFlag) {
160 			this.putGlobalError("role.required");
161 		}
162 
163 		return valid & activeFlag;
164 	}
165 
166 	@Override
167 	public boolean processCustomAddCollectionLineBusinessRules(
168 			MaintenanceDocument document, String collectionName,
169 			PersistableBusinessObject line) {
170 		boolean valid = true;
171 		
172 		//TODO: Do we really need to use member type, id, role id? If there are duplicate role names listed in the drop downs, this is just going to cause confusion...
173 		if(line instanceof DepartmentPrincipalRoleMemberBo) {
174 			DepartmentPrincipalRoleMemberBo roleMember = (DepartmentPrincipalRoleMemberBo) line;
175 			Department location = (Department) document.getDocumentBusinessObject();
176 			List<DepartmentPrincipalRoleMemberBo> existingRoleMembers = location.getRoleMembers();
177 			for(ListIterator<DepartmentPrincipalRoleMemberBo> iter = existingRoleMembers.listIterator(); iter.hasNext(); ) {
178 				int index = iter.nextIndex();
179 	            String prefix = "roleMembers[" + index + "].";
180 				DepartmentPrincipalRoleMemberBo existingRoleMember = iter.next();
181 				if(StringUtils.equals(existingRoleMember.getPrincipalId(),roleMember.getPrincipalId())) {
182 					if(StringUtils.equals(existingRoleMember.getRoleName(),roleMember.getRoleName())) {
183 						if(existingRoleMember.getActiveToDate() != null) {
184 							if(roleMember.getActiveFromDate().compareTo(existingRoleMember.getActiveToDate()) < 0) {
185 								valid &= false;
186 								this.putFieldError(prefix + "effectiveDate", "error.role.active.existence");
187 								this.putFieldError("add.roleMembers.effectiveDate", "error.role.active.duplicate");
188 							}
189 						}
190 						else {
191 							valid &= false;
192 							this.putFieldError(prefix + "effectiveDate", "error.role.active.existence");
193 							this.putFieldError("add.roleMembers.effectiveDate", "error.role.active.duplicate");
194 						}
195 					}
196 				}
197 			}
198 			existingRoleMembers = location.getInactiveRoleMembers();
199 			for(ListIterator<DepartmentPrincipalRoleMemberBo> iter = existingRoleMembers.listIterator(); iter.hasNext(); ) {
200 				int index = iter.nextIndex();
201 	            String prefix = "inactiveRoleMembers[" + index + "].";
202 				DepartmentPrincipalRoleMemberBo existingRoleMember = iter.next();
203 				if(StringUtils.equals(existingRoleMember.getPrincipalId(),roleMember.getPrincipalId())) {
204 					if(StringUtils.equals(existingRoleMember.getRoleName(),roleMember.getRoleName())) {
205 						if(existingRoleMember.getActiveToDate() != null) {
206 							if(roleMember.getActiveFromDate().compareTo(existingRoleMember.getActiveToDate()) < 0) {
207 								valid &= false;
208 								this.putFieldError(prefix + "effectiveDate", "error.role.inactive.existence");
209 								this.putFieldError("add.roleMembers.effectiveDate", "error.role.inactive.duplicate");
210 							}
211 						}
212 						else {
213 							valid &= false;
214 							this.putFieldError(prefix + "effectiveDate", "error.role.inactive.existence");
215 							this.putFieldError("add.roleMembers.effectiveDate", "error.role.inactive.duplicate");
216 						}
217 					}
218 				}
219 			}
220 		}
221 		
222 		return valid;
223 	}
224 
225 }