1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.core.assignment.validation;
17
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.ListIterator;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.joda.time.DateTime;
27 import org.joda.time.LocalDate;
28 import org.kuali.kpme.core.api.assignment.Assignment;
29 import org.kuali.kpme.core.api.assignment.AssignmentContract;
30 import org.kuali.kpme.core.api.earncode.EarnCodeContract;
31 import org.kuali.kpme.core.api.job.JobContract;
32 import org.kuali.kpme.core.api.paytype.PayType;
33 import org.kuali.kpme.core.api.task.Task;
34 import org.kuali.kpme.core.api.task.TaskContract;
35 import org.kuali.kpme.core.assignment.AssignmentBo;
36 import org.kuali.kpme.core.assignment.account.AssignmentAccountBo;
37 import org.kuali.kpme.core.service.HrServiceLocator;
38 import org.kuali.kpme.core.util.ValidationUtils;
39 import org.kuali.rice.krad.bo.PersistableBusinessObject;
40 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
41 import org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase;
42 import org.kuali.rice.krad.util.GlobalVariables;
43
44 @SuppressWarnings("deprecation")
45 public class AssignmentRule extends MaintenanceDocumentRuleBase {
46
47 protected boolean validateWorkArea(AssignmentBo assignment) {
48 boolean valid = true;
49 if (assignment.getWorkArea() != null) {
50 if (!ValidationUtils.validateWorkArea(assignment.getWorkArea(),
51 assignment.getEffectiveLocalDate())) {
52 this.putFieldError("dataObject.workArea", "error.existence", "workArea '"
53 + assignment.getWorkArea() + "'");
54 valid = false;
55 } else {
56 int count = HrServiceLocator.getWorkAreaService().getWorkAreaCount(assignment.getDept(), assignment.getWorkArea());
57 valid = (count > 0);
58 if (!valid) {
59 this.putFieldError("dataObject.workArea", "dept.workarea.invalid.sync");
60 }
61 }
62 }
63 return valid;
64 }
65
66 protected boolean validateTask(AssignmentBo assignment) {
67 boolean valid = false;
68
69 if (assignment.getTask() != null && !assignment.getTask().equals(0L)) {
70
71 String workarea = "";
72 if(assignment.getWorkArea() != null) {
73 workarea = assignment.getWorkArea().toString();
74 }
75 List<Task> tasks = HrServiceLocator.getTaskService().getTasks(assignment.getTask().toString(), null, workarea, null, assignment.getEffectiveLocalDate());
76 for(Task task : tasks) {
77 if(workarea.equals(task.getWorkArea().toString())) {
78 valid = true;
79 return valid;
80 }
81 }
82 } else {
83 valid = true;
84 return valid;
85 }
86 this.putFieldError("dataObject.task", "task.workarea.invalid.sync");
87 return valid;
88 }
89
90 protected boolean validateDepartment(AssignmentBo assignment) {
91 boolean valid = true;
92 if (assignment.getDept() != null) {
93 int count = HrServiceLocator.getJobService().getJobCount(null, assignment.getJobNumber(), assignment.getDept());
94 valid = (count > 0);
95 if (!valid) {
96 this.putFieldError("dataObject.dept", "dept.jobnumber.invalid.sync");
97 }
98
99 }
100 return valid;
101 }
102
103 protected boolean validateJob(AssignmentBo assignment) {
104 boolean valid = false;
105 LOG.debug("Validating job: " + assignment.getPrincipalId() +" Job number: "+assignment.getJobNumber());
106 JobContract job = HrServiceLocator.getJobService().getJob(
107 assignment.getPrincipalId(), assignment.getJobNumber(),
108 assignment.getEffectiveLocalDate(), false);
109 if (job != null) {
110 valid = true;
111
112 LOG.debug("found job.");
113 } else {
114 this.putFieldError("dataObject.jobNumber", "error.existence", "jobNumber '"
115 + assignment.getJobNumber() + "'");
116 }
117 return valid;
118 }
119
120 protected boolean validatePercentagePerEarnCode(AssignmentBo assignment) {
121 boolean valid = true;
122 LOG.debug("Validating PercentagePerEarnCode: ");
123 List<AssignmentAccountBo> assignmentAccounts = assignment
124 .getAssignmentAccounts();
125 Set<String> invalidEarnCodes = null;
126 if (assignmentAccounts != null && assignment.isActive()) {
127 Map<String, Integer> earnCodePercent = new HashMap<String, Integer>();
128 for (AssignmentAccountBo account : assignmentAccounts) {
129 if (account.getPercent() != null && account.isActive()) {
130 int percent = 0;
131 if (earnCodePercent.containsKey(account.getEarnCode())) {
132 percent = earnCodePercent.get(account.getEarnCode());
133 }
134 percent += account.getPercent().toBigInteger().intValue();
135 earnCodePercent.put(account.getEarnCode(), percent);
136 }
137 }
138
139 for (Map.Entry<String, Integer> entry : earnCodePercent.entrySet()) {
140
141 String earnCode = entry.getKey();
142 if (entry.getValue() != 100) {
143 if (invalidEarnCodes == null) {
144 invalidEarnCodes = new HashSet<String>();
145 }
146 invalidEarnCodes.add(earnCode);
147 valid = false;
148 }
149 }
150 if (!valid) {
151 int index = 0;
152 for (AssignmentAccountBo account : assignmentAccounts) {
153 if (invalidEarnCodes.contains(account.getEarnCode())) {
154 this.putFieldError("dataObject.assignmentAccounts[" + index
155 + "].percent", "error.percentage.earncode");
156 }
157 index++;
158 }
159 }
160 }
161 return valid;
162 }
163
164 protected boolean validateEarnCode(AssignmentAccountBo assignmentAccount, LocalDate assignmentEffectiveDate) {
165 boolean valid = false;
166 LOG.debug("Validating EarnCode: " + assignmentAccount.getEarnCode());
167 EarnCodeContract earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(
168 assignmentAccount.getEarnCode(), assignmentEffectiveDate);
169 if (earnCode != null) {
170
171 valid = true;
172 LOG.debug("found earnCode.");
173 } else {
174 this.putGlobalError("error.existence", "earn code '"
175 + assignmentAccount.getEarnCode() + "'");
176 }
177 return valid;
178 }
179
180 protected boolean validateRegPayEarnCode(AssignmentBo assignment) {
181 boolean valid = false;
182 LOG.debug("Validating Regular pay EarnCodes: " + assignment.getAssignmentAccounts().size());
183 for(AssignmentAccountBo assignmentAccount : assignment.getAssignmentAccounts()){
184 if(assignment.getJobNumber()!=null && assignment.getPrincipalId()!=null){
185 JobContract job = HrServiceLocator.getJobService().getJob(assignment.getPrincipalId(), assignment.getJobNumber(), assignment.getEffectiveLocalDate(), false);
186 if(job !=null){
187 PayType payType = HrServiceLocator.getPayTypeService().getPayType(job.getHrPayType(), assignment.getEffectiveLocalDate());
188 if(StringUtils.equals(assignmentAccount.getEarnCode(), payType.getRegEarnCode())){
189 valid = true;
190 break;
191 }
192
193 }
194 }
195 }
196 if(!valid) {
197 this.putFieldError("dataObject.assignmentAccounts", "earncode.regular.pay.required");
198 }
199 return valid;
200 }
201
202
203 protected boolean validateAccounts(AssignmentBo assignment) {
204 boolean valid = false;
205 LOG.debug("Validating Accounts: " + assignment.getAssignmentAccounts().size());
206 for(AssignmentAccountBo assignmentAccount : assignment.getAssignmentAccounts()){
207 valid = ValidationUtils.validateAccount(assignmentAccount.getFinCoaCd(), assignmentAccount.getAccountNbr());
208 if(!valid) {
209 this.putFieldError("dataObject.assignmentAccounts", "error.existence", "Account Number '" + assignmentAccount.getAccountNbr() + "'");
210 break;
211 }
212 }
213 return valid;
214 }
215
216 protected boolean validateAccount(AssignmentAccountBo assignmentAccount) {
217 boolean valid = false;
218 LOG.debug("Validating Account: " + assignmentAccount.getAccountNbr());
219 valid = ValidationUtils.validateAccount(assignmentAccount.getFinCoaCd(),assignmentAccount.getAccountNbr());
220 if (!valid) {
221 this.putGlobalError("error.existence", "Account Number '"
222 + assignmentAccount.getAccountNbr() + "'");
223 }
224 return valid;
225 }
226
227 private boolean validateSubAccount(AssignmentAccountBo assignmentAccount) {
228 boolean valid = false;
229 LOG.debug("Validating Sub-Account: " + assignmentAccount.getSubAcctNbr());
230 valid = ValidationUtils.validateSubAccount(assignmentAccount.getSubAcctNbr(),assignmentAccount.getAccountNbr(), assignmentAccount.getFinCoaCd());
231 if (!valid) {
232 this.putGlobalError("error.existence", "Sub-Account Number '"
233 + assignmentAccount.getSubAcctNbr() + "'");
234 }
235 return valid;
236 }
237
238 protected boolean validateObjectCode(AssignmentAccountBo assignmentAccount, LocalDate assignmentEffectiveDate) {
239 boolean valid = false;
240 LOG.debug("Validating ObjectCode: "
241 + assignmentAccount.getFinObjectCd());
242 valid = ValidationUtils.validateObjectCode(assignmentAccount.getFinObjectCd(),
243 assignmentAccount.getFinCoaCd(),
244 null);
245 if (!valid) {
246 this.putGlobalError("error.existence", "Object Code '"
247 + assignmentAccount.getFinObjectCd() + "'");
248 }
249 return valid;
250 }
251
252 protected boolean validateSubObjectCode(AssignmentAccountBo assignmentAccount, LocalDate assignmentEffectiveDate) {
253 boolean valid = false;
254 LOG.debug("Validating SubObjectCode: "
255 + assignmentAccount.getFinSubObjCd());
256 if (assignmentAccount.getFinSubObjCd() != null) {
257 valid = ValidationUtils.validateSubObjectCode(String.valueOf(assignmentEffectiveDate.getYear()),
258 assignmentAccount.getFinCoaCd(),
259 assignmentAccount.getAccountNbr(),
260 assignmentAccount.getFinObjectCd(),
261 assignmentAccount.getFinSubObjCd());
262 if (!valid) {
263 this.putGlobalError("error.existence", "SubObject Code '"
264 + assignmentAccount.getFinSubObjCd() + "'");
265 }
266 } else {
267 valid = true;
268 }
269 return valid;
270 }
271
272 protected boolean validateHasAccounts(AssignmentBo assign){
273 if(assign.getAssignmentAccounts().isEmpty()){
274 this.putGlobalError("error.assign.must.have.one.or.more.account");
275 return false;
276 }
277 return true;
278 }
279
280 protected boolean validateOnePrimaryAssignment(AssignmentBo assignment, AssignmentBo oldAssignment) {
281 if (assignment.isPrimaryAssign()) {
282
283 if(oldAssignment!=null && oldAssignment.isPrimaryAssign()){
284 return true;
285 }
286 JobContract job = HrServiceLocator.getJobService().getJob(assignment.getPrincipalId(), assignment.getJobNumber(), assignment.getEffectiveLocalDate(), false);
287 if(job != null && job.isEligibleForLeave()) {
288 List<Assignment> assignList = HrServiceLocator.getAssignmentService().getActiveAssignmentsForJob(assignment.getPrincipalId(), assignment.getJobNumber(), assignment.getEffectiveLocalDate());
289 for(Assignment anAssignment : assignList) {
290 if(anAssignment != null && anAssignment.isPrimaryAssign()) {
291 this.putFieldError("dataObject.primaryAssign", "error.primary.assignment.exists.for.leaveJob", assignment.getJobNumber().toString());
292 return false;
293 }
294 }
295 }
296 }
297 return true;
298 }
299
300 protected boolean validateActiveFlag(AssignmentBo assign){
301 if (assign.isActive()) {
302 return true;
303 }
304 Assignment assignment = AssignmentBo.to(assign);
305 DateTime latestTimeEndTimestamp = HrServiceLocator.getCalendarBlockService().getLatestEndTimestampForAssignment(assignment,"Time");
306
307 if(latestTimeEndTimestamp != null) {
308 LocalDate assignmentEffectiveDate = assign.getEffectiveLocalDate();
309 LocalDate latestTimeEndTimestampLocalDate = latestTimeEndTimestamp.toLocalDate();
310
311 if ( !assign.isActive() && !assignmentEffectiveDate.isAfter(latestTimeEndTimestampLocalDate) ){
312 this.putFieldError("active", "error.assignment.timeblock.existence", latestTimeEndTimestampLocalDate.toString());
313 return false;
314 }
315 }
316
317 DateTime latestLeaveEndTimestamp = HrServiceLocator.getCalendarBlockService().getLatestEndTimestampForAssignment(assignment,"Leave");
318 if(latestLeaveEndTimestamp!=null) {
319 LocalDate assignmentEffectiveDate = assign.getEffectiveLocalDate();
320 LocalDate latestLeaveEndTimestampLocalDate = latestLeaveEndTimestamp.toLocalDate();
321
322 if ( !assign.isActive() && !assignmentEffectiveDate.isAfter(latestLeaveEndTimestampLocalDate) ){
323 this.putFieldError("active", "error.assignment.leaveblock.existence", latestLeaveEndTimestampLocalDate.toString());
324 return false;
325 }
326 }
327
328 return true;
329 }
330
331
332
333
334
335 @Override
336 protected boolean processCustomRouteDocumentBusinessRules(
337 MaintenanceDocument document) {
338 boolean valid = false;
339 LOG.debug("entering custom validation for Assignment");
340 PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewDataObject();
341 if (pbo instanceof AssignmentBo) {
342 AssignmentBo assignment = (AssignmentBo) pbo;
343 if (assignment != null) {
344 valid = true;
345 valid &= this.validateWorkArea(assignment);
346 valid &= this.validateTask(assignment);
347 valid &= this.validateJob(assignment);
348 valid &= this.validateDepartment(assignment);
349 valid &= this.validatePercentagePerEarnCode(assignment);
350 valid &= this.validateHasAccounts(assignment);
351 valid &= this.validateActiveFlag(assignment);
352 if(!assignment.getAssignmentAccounts().isEmpty()) {
353 valid &= this.validateRegPayEarnCode(assignment);
354
355
356 for (ListIterator<AssignmentAccountBo> iterator = assignment.getAssignmentAccounts().listIterator() ; iterator.hasNext();){
357 int index = iterator.nextIndex();
358 AssignmentAccountBo assignmentAccountBo = iterator.next();
359 valid &= this.validateAssignmentAccount(assignmentAccountBo, assignment, index);
360 }
361 }
362
363 if(assignment.isPrimaryAssign()) {
364 AssignmentBo oldAssignment = (AssignmentBo) this.getOldDataObject();
365 valid &= this.validateOnePrimaryAssignment(assignment, oldAssignment);
366 }
367 }
368 }
369
370 return valid;
371 }
372
373 @Override
374 public boolean processCustomAddCollectionLineBusinessRules(
375 MaintenanceDocument document, String collectionName,
376 PersistableBusinessObject line) {
377 boolean valid = false;
378 LOG.debug("entering custom add assignment account business rules");
379 PersistableBusinessObject assignmentPbo = (PersistableBusinessObject) this.getNewDataObject();
380 PersistableBusinessObject pbo = line;
381 if (pbo instanceof AssignmentAccountBo) {
382 AssignmentAccountBo assignmentAccount = (AssignmentAccountBo) pbo;
383 if (assignmentAccount != null) {
384 if(assignmentPbo instanceof AssignmentBo) {
385 AssignmentBo assignment = (AssignmentBo) assignmentPbo;
386 valid = true;
387 valid &= this.validateEarnCode(assignmentAccount, assignment.getEffectiveLocalDate());
388 valid &= this.validateAccount(assignmentAccount);
389 valid &= this.validateObjectCode(assignmentAccount, assignment.getEffectiveLocalDate());
390 valid &= this.validateSubObjectCode(assignmentAccount, assignment.getEffectiveLocalDate());
391 if(assignmentAccount.getSubAcctNbr() != null && !assignmentAccount.getSubAcctNbr().isEmpty()) {
392 valid &= this.validateSubAccount(assignmentAccount);
393 }
394 }
395 }
396 }
397 return valid;
398 }
399
400
401 private boolean validateAssignmentAccount(AssignmentAccountBo assignmentAccount, AssignmentBo assignmentObj, int index) {
402 boolean isValid = true;
403 String prefix = "assignmentAccounts";
404 String propertyNamePrefix = prefix + "[" + index + "].";
405 if(StringUtils.isNotEmpty(assignmentAccount.getEarnCode())) {
406 boolean valid = ValidationUtils.validateEarnCode(assignmentAccount.getEarnCode(), assignmentObj.getEffectiveLocalDate());
407 if(!valid) {
408 this.putFieldError(propertyNamePrefix + "earnCode","error.existence", "earn code '"+ assignmentAccount.getEarnCode() + "'");
409 isValid = false;
410 }
411 }
412 if(StringUtils.isNotEmpty(assignmentAccount.getAccountNbr())) {
413 boolean valid = ValidationUtils.validateAccount(assignmentAccount.getFinCoaCd(),assignmentAccount.getAccountNbr());
414 if(!valid) {
415 this.putFieldError(propertyNamePrefix + "accountNbr","error.existence", "Account Number '"+ assignmentAccount.getAccountNbr() + "'");
416 isValid = false;
417 }
418 }
419 if(StringUtils.isNotEmpty(assignmentAccount.getFinObjectCd())) {
420 boolean valid = ValidationUtils.validateObjectCode(assignmentAccount.getFinObjectCd(),assignmentAccount.getFinCoaCd(),null);
421 if (!valid) {
422 this.putFieldError(propertyNamePrefix + "finObjectCd","error.existence", "Object Code '"+ assignmentAccount.getFinObjectCd() + "'");
423 isValid = false;
424 }
425 }
426 if (StringUtils.isNotEmpty(assignmentAccount.getFinSubObjCd())) {
427 boolean valid = ValidationUtils.validateSubObjectCode(String.valueOf(assignmentObj.getEffectiveLocalDate().getYear()),assignmentAccount.getFinCoaCd(),
428 assignmentAccount.getAccountNbr(), assignmentAccount.getFinObjectCd(), assignmentAccount.getFinSubObjCd());
429 if (!valid) {
430 this.putFieldError(propertyNamePrefix + "finSubObjCd","error.existence", "SubObject Code '"+ assignmentAccount.getFinSubObjCd() + "'");
431 isValid = false;
432 }
433 }
434 if(assignmentAccount.getSubAcctNbr() != null && StringUtils.isNotEmpty(assignmentAccount.getSubAcctNbr())) {
435 boolean valid = ValidationUtils.validateSubAccount(assignmentAccount.getSubAcctNbr(),assignmentAccount.getAccountNbr(), assignmentAccount.getFinCoaCd());
436 if (!valid) {
437 this.putFieldError(propertyNamePrefix + "subAcctNbr", "error.existence", "Sub-Account Number '"+ assignmentAccount.getSubAcctNbr() + "'");
438 isValid = false;
439 }
440 }
441
442 return isValid;
443 }
444
445
446
447 }