001 /** 002 * Copyright 2004-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.hr.lm.leaveCalendar.validation; 017 018 import java.math.BigDecimal; 019 import java.util.ArrayList; 020 import java.util.List; 021 import java.util.Map; 022 import java.util.Set; 023 024 import org.joda.time.LocalDate; 025 import org.junit.After; 026 import org.junit.Assert; 027 import org.junit.Before; 028 import org.junit.Test; 029 import org.kuali.hr.KPMEWebTestCase; 030 import org.kuali.kpme.core.FunctionalTest; 031 import org.kuali.kpme.tklm.leave.block.LeaveBlock; 032 import org.kuali.kpme.tklm.leave.calendar.validation.LeaveCalendarValidationUtil; 033 import org.kuali.kpme.tklm.leave.summary.LeaveSummary; 034 import org.kuali.kpme.tklm.leave.summary.LeaveSummaryRow; 035 036 @FunctionalTest 037 public class LeaveCalendarValidationServiceTest extends KPMEWebTestCase { 038 039 @Before 040 public void setUp() throws Exception { 041 super.setUp(); 042 } 043 044 @After 045 public void tearDown() throws Exception { 046 super.tearDown(); 047 } 048 049 @Test 050 public void testValidateAvailableLeaveBalance() throws Exception { 051 LeaveSummary ls = new LeaveSummary(); 052 LeaveSummaryRow lsr = new LeaveSummaryRow(); 053 lsr.setAccrualCategory("testAC"); 054 lsr.setAccrualCategoryId("5000"); 055 lsr.setLeaveBalance(new BigDecimal(5)); 056 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 057 lsrList.add(lsr); 058 ls.setLeaveSummaryRows(lsrList); 059 060 // adding brand new leave blocks 061 // earn code "EC" does not allow negative accrual balance 062 List<String> errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(8), null); 063 Assert.assertEquals("Incorrect number of error messages", 1, errors.size()); 064 String anError = errors.get(0); 065 Assert.assertTrue("error message not correct" , anError.equals("Requested leave amount 8 is greater than available leave balance 0.00")); 066 067 // earn code "EC1" allows negative accrual balance 068 errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC1", "02/15/2012", "02/15/2012", new BigDecimal(8), null); 069 Assert.assertTrue("There should NOT be error message(s)" , errors.isEmpty()); 070 071 //updating an existing leave block 072 LeaveBlock aLeaveBlock = new LeaveBlock(); 073 aLeaveBlock.setEarnCode("EC"); 074 aLeaveBlock.setLeaveAmount(new BigDecimal(-10)); 075 076 errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(3), aLeaveBlock); 077 Assert.assertTrue("There should NOT be error message(s)" , errors.isEmpty()); 078 079 aLeaveBlock.setLeaveAmount(new BigDecimal(-2)); 080 errors = LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage("EC", "02/15/2012", "02/15/2012", new BigDecimal(10), aLeaveBlock); 081 anError = errors.get(0); 082 Assert.assertTrue("error message not correct" , anError.equals("Requested leave amount 10 is greater than available leave balance 2.00")); 083 } 084 085 @Test 086 public void testValidateLeaveSpanOverMaxUsageRule() throws Exception { 087 LeaveSummary ls = new LeaveSummary(); 088 LeaveSummaryRow lsr = new LeaveSummaryRow(); 089 lsr.setAccrualCategory("testAC"); 090 lsr.setUsageLimit(new BigDecimal(39)); 091 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 092 lsrList.add(lsr); 093 ls.setLeaveSummaryRows(lsrList); 094 // adding brand new leave blocks 095 List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null); 096 Assert.assertEquals("There should be 1 error message" , 1, errors.size()); 097 String anError = errors.get(0); 098 Assert.assertTrue("error message not correct" , anError.equals("This leave request would exceed the usage limit for " + lsr.getAccrualCategory())); 099 } 100 101 @Test 102 public void testValidateLeaveSpanUnderMaxUsageRule() throws Exception { 103 LeaveSummary ls = new LeaveSummary(); 104 LeaveSummaryRow lsr = new LeaveSummaryRow(); 105 lsr.setAccrualCategory("testAC"); 106 lsr.setUsageLimit(new BigDecimal(41)); 107 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 108 lsrList.add(lsr); 109 ls.setLeaveSummaryRows(lsrList); 110 // adding brand new leave blocks 111 List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null); 112 Assert.assertEquals("There should be no error message" , 0, errors.size()); 113 } 114 115 @Test 116 public void testValidateLeaveSpanEqualMaxUsageRule() throws Exception { 117 LeaveSummary ls = new LeaveSummary(); 118 LeaveSummaryRow lsr = new LeaveSummaryRow(); 119 lsr.setAccrualCategory("testAC"); 120 lsr.setUsageLimit(new BigDecimal(40)); 121 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 122 lsrList.add(lsr); 123 ls.setLeaveSummaryRows(lsrList); 124 // adding brand new leave blocks 125 List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(8), null); 126 Assert.assertEquals("There should be no error message" , 0, errors.size()); 127 } 128 129 @Test 130 public void testValidateLeaveNonSpanOverMaxUsageRule() throws Exception { 131 LeaveSummary ls = new LeaveSummary(); 132 LeaveSummaryRow lsr = new LeaveSummaryRow(); 133 lsr.setAccrualCategory("testAC"); 134 lsr.setUsageLimit(new BigDecimal(5)); 135 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 136 lsrList.add(lsr); 137 ls.setLeaveSummaryRows(lsrList); 138 // adding brand new leave blocks 139 List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(8), null); 140 Assert.assertEquals("There should be 1 error message" , 1, errors.size()); 141 String anError = errors.get(0); 142 Assert.assertTrue("error message not correct" , anError.equals("This leave request would exceed the usage limit for " + lsr.getAccrualCategory())); 143 } 144 145 @Test 146 public void testValidateLeaveNonSpanEqualsMaxUsageRule() throws Exception { 147 LeaveSummary ls = new LeaveSummary(); 148 LeaveSummaryRow lsr = new LeaveSummaryRow(); 149 lsr.setAccrualCategory("testAC"); 150 lsr.setUsageLimit(new BigDecimal(5)); 151 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 152 lsrList.add(lsr); 153 ls.setLeaveSummaryRows(lsrList); 154 155 List<String> errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(5), null); 156 Assert.assertEquals("There should be no error message" , 0, errors.size()); 157 158 } 159 160 @Test 161 public void testValidateEditLeaveBlockMaxUsageRuleCaseOne() throws Exception { 162 //Leave Amount increases, Earn Code unchanged 163 LeaveSummary ls = new LeaveSummary(); 164 LeaveSummaryRow lsr = new LeaveSummaryRow(); 165 lsr.setAccrualCategory("testAC"); 166 lsr.setUsageLimit(new BigDecimal(50)); 167 lsr.setPendingLeaveRequests(new BigDecimal(25)); 168 lsr.setYtdApprovedUsage(new BigDecimal(15)); 169 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 170 lsrList.add(lsr); 171 ls.setLeaveSummaryRows(lsrList); 172 173 //updating an existing leave block 174 LeaveBlock aLeaveBlock = new LeaveBlock(); 175 aLeaveBlock.setEarnCode("EC"); 176 aLeaveBlock.setLeaveAmount(new BigDecimal(-10)); //this amount, multiplied by the days in the span, is considered to be part of the pending leave requests. 177 List<String> errors = new ArrayList<String>(); 178 179 // EC1 belongs to the accrual category testAC 180 // should still be under 50 effective difference is +9, over 1 days = 9 -> 40+12 < 50 181 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(19), aLeaveBlock); 182 Assert.assertTrue("There should be no error message test 1" , errors.size()== 0); 183 184 // should be right at 50 effective difference is +10, over 1 days = 10 -> 40+10 = 50 185 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(20), aLeaveBlock); 186 Assert.assertTrue("There should be no error message test 2" , errors.size()== 0); 187 188 // should be over 50 effective difference is +11, over 1 day = 11 -> 40+11 > 50 189 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(21), aLeaveBlock); 190 Assert.assertTrue("There should be 1 error message test 3" , errors.size()== 1); 191 192 // should be over 50 effective difference is +2, over 6 days = 12 -> 40+12 > 50 193 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/20/2012", new BigDecimal(12), aLeaveBlock); 194 Assert.assertTrue("There should be 1 error message test 5" , errors.size()== 1); 195 196 // should be under effective difference is +2, over 4 days = 8 -> 40+8 < 50 197 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/18/2012", new BigDecimal(12), aLeaveBlock); 198 Assert.assertTrue("There should be 1 error message test 6" , errors.size()== 1); 199 } 200 201 @Test 202 public void testValidateEditLeaveBlockMaxUsageRuleCaseTwo() throws Exception { 203 //Leave Amount decreases, earn code remains the same. 204 LeaveSummary ls = new LeaveSummary(); 205 LeaveSummaryRow lsr = new LeaveSummaryRow(); 206 lsr.setAccrualCategory("testAC"); 207 lsr.setUsageLimit(new BigDecimal(50)); 208 lsr.setPendingLeaveRequests(new BigDecimal(25)); 209 lsr.setYtdApprovedUsage(new BigDecimal(30)); 210 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 211 lsrList.add(lsr); 212 ls.setLeaveSummaryRows(lsrList); 213 214 //updating an existing leave block 215 //Somehow a block enters the system that exceeds max_usage. The only way for it to be saved 216 //is if the net change drops below the usage limit. 217 LeaveBlock aLeaveBlock = new LeaveBlock(); 218 aLeaveBlock.setEarnCode("EC"); 219 aLeaveBlock.setLeaveAmount(new BigDecimal(-10)); 220 List<String> errors = new ArrayList<String>(); 221 222 // effective difference is (-2), over 1 days = -2 -> 55+(-2) > 50 223 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/15/2012", new BigDecimal(8), aLeaveBlock); 224 Assert.assertTrue("There should be 1 error message" , errors.size()== 1); 225 226 // should be equal effective difference is (-0.5), over 5 days = -2.5 -> 55+(-2.5) > 50 227 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC", "02/15/2012", "02/19/2012", new BigDecimal(9.5), aLeaveBlock); 228 Assert.assertTrue("There should be 1 error message" , errors.size()== 1); 229 } 230 231 @Test 232 public void testValidateEditLeaveBlockMaxUsageRuleCaseThree() throws Exception { 233 //Leave Amount static, earn code changes. 234 LeaveSummary ls = new LeaveSummary(); 235 LeaveSummaryRow lsr = new LeaveSummaryRow(); 236 lsr.setAccrualCategory("testAC"); 237 lsr.setUsageLimit(new BigDecimal(50)); 238 lsr.setPendingLeaveRequests(new BigDecimal(25)); 239 lsr.setYtdApprovedUsage(new BigDecimal(15)); 240 241 LeaveSummaryRow lsr2 = new LeaveSummaryRow(); 242 lsr2.setAccrualCategory("testAC2"); 243 lsr2.setUsageLimit(new BigDecimal(15)); 244 lsr2.setPendingLeaveRequests(new BigDecimal(5)); 245 lsr2.setYtdApprovedUsage(new BigDecimal(4)); 246 247 List<LeaveSummaryRow> lsrList = new ArrayList<LeaveSummaryRow>(); 248 lsrList.add(lsr); 249 lsrList.add(lsr2); 250 ls.setLeaveSummaryRows(lsrList); 251 252 //updating an existing leave block 253 LeaveBlock aLeaveBlock = new LeaveBlock(); 254 aLeaveBlock.setEarnCode("EC"); 255 aLeaveBlock.setAccrualCategory("testAC"); 256 aLeaveBlock.setLeaveAmount(new BigDecimal(-10)); 257 List<String> errors = new ArrayList<String>(); 258 259 //Changing to an earn code with different accrual category, testAC2 260 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/15/2012", new BigDecimal(6), aLeaveBlock); 261 Assert.assertTrue("There should be no error message. reached usage limit." , errors.size()== 0); 262 263 //Changing to an earn code with different accrual category, testAC2 264 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/15/2012", new BigDecimal(7), aLeaveBlock); 265 Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1); 266 267 //Changing to an earn code with different accrual category, testAC2 with spanning days. 268 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/19/2012", new BigDecimal(1), aLeaveBlock); 269 Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0); 270 271 //Changing to an earn code with different accrual category, testAC2 with spanning days. 272 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/20/2012", new BigDecimal(1), aLeaveBlock); 273 Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0); 274 275 //Changing to an earn code with different accrual category, testAC2 with spanning days. 276 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/21/2012", new BigDecimal(1), aLeaveBlock); 277 Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1); 278 279 //Changing to an earn code within same accrual category, testAC 280 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC1", "02/15/2012", "02/15/2012", new BigDecimal(10), aLeaveBlock); 281 Assert.assertTrue("There should be no error message, there were " + errors.size() + " errors" , errors.size()== 0); 282 283 //Changing to an earn code within same accrual category, testAC with spanning days. 284 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC1", "02/15/2012", "02/19/2012", new BigDecimal(2), aLeaveBlock); 285 Assert.assertTrue("There should be 0 error message, there were " + errors.size() + " errors" , errors.size()== 0); 286 287 //Changing to an earn code within same accrual category, testAC with spanning days. 288 errors = LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, "EC2", "02/15/2012", "02/25/2012", new BigDecimal(1), aLeaveBlock); 289 Assert.assertTrue("There should be 1 error message, there were " + errors.size() + " errors" , errors.size()== 1); 290 291 } 292 @Test 293 public void testGetWarningTextForLeaveBlocks() throws Exception { 294 // create two leave blocks with two different earn codes 295 // earn code "ECA" has fmla=Y, has earn code group with warning messages 296 // earn Code "ECB" has fmla = N, has earn code group with warning messages 297 // earn code "ECC" does not have earn code group with warning messages 298 299 List<LeaveBlock> leaveBlocs = new ArrayList<LeaveBlock>(); 300 LeaveBlock lbA = new LeaveBlock(); 301 lbA.setEarnCode("ECA"); 302 lbA.setLeaveDate(LocalDate.now().toDate()); 303 leaveBlocs.add(lbA); 304 305 LeaveBlock lbB = new LeaveBlock(); 306 lbB.setEarnCode("ECB"); 307 lbB.setLeaveDate(LocalDate.now().toDate()); 308 leaveBlocs.add(lbB); 309 310 LeaveBlock lbC = new LeaveBlock(); 311 lbC.setEarnCode("ECC"); 312 lbC.setLeaveDate(LocalDate.now().toDate()); 313 leaveBlocs.add(lbC); 314 315 Map<String, Set<String>> allMessages = LeaveCalendarValidationUtil.getWarningMessagesForLeaveBlocks(leaveBlocs); 316 int numberOfMessages = 0; 317 for (Set<String> msgs : allMessages.values()){ 318 numberOfMessages += msgs.size(); 319 } 320 Assert.assertTrue("There should be 2 warning messages, not " + numberOfMessages, numberOfMessages== 2); 321 322 for (Set<String> msgs : allMessages.values()){ 323 for (String message : msgs) { 324 Assert.assertTrue("Warning message should be 'Test Message' or 'Test Message1'", message.equals("Test Message") || message.equals("Test Message1")); 325 } 326 } 327 } 328 329 /* In order for tests of the following form to work, need to change status of a document to enroute/approved 330 * without actually routing / approving the document. OR, set up a context within which these actions can be performed. 331 */ 332 /* @Test 333 public void testValidatePendingTransactions() throws Exception { 334 Assert.assertNull(null); 335 BalanceTransfer bt = new BalanceTransfer(); 336 bt.setAmountTransferred(new BigDecimal(1.0)); 337 bt.setTransferAmount(new BigDecimal(1.0)); 338 bt.setForfeitedAmount(new BigDecimal(1.0)); 339 bt.setAccrualCategoryRule(""); 340 bt.setEffectiveDate(TKUtils.getCurrentDate()); 341 bt.setFromAccrualCategory("testAC"); 342 bt.setToAccrualCategory("testAC2"); 343 bt.setPrincipalId("admin"); 344 345 mockSubmitToWorkflow(bt); 346 347 Calendar cal = Calendar.getInstance(); 348 cal.setTime(TKUtils.getCurrentDate()); 349 cal.add(Calendar.MONTH, -1); 350 Date from = cal.getTime(); 351 cal.add(Calendar.MONTH, 2); 352 Date to = cal.getTime(); 353 Map<String,Set<String>> allMessages = new HashMap<String, Set<String>>(); 354 allMessages.putAll(LeaveCalendarValidationUtil.validatePendingTransactions("admin", LocalDate.fromDateFields(from), LocalDate.fromDateFields(to))); 355 356 Assert.assertTrue(allMessages.get("actionMessages").size() > 0); 357 Set<String> actionMessages = allMessages.get("actionMessage"); 358 359 Assert.assertTrue("Should contain warning message for pending transaction", actionMessages.contains("A pending balance transfer exists on this calendar. " + 360 "It must be finalized before this calendar can be approved")); 361 } 362 363 private void mockSubmitToWorkflow(BalanceTransfer balanceTransfer) { 364 // TODO Auto-generated method stub 365 //balanceTransfer.setStatus(HrConstants.ROUTE_STATUS.ENROUTE); 366 EntityNamePrincipalName principalName = null; 367 if (balanceTransfer.getPrincipalId() != null) { 368 principalName = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(balanceTransfer.getPrincipalId()); 369 } 370 371 MaintenanceDocument document = KRADServiceLocatorWeb.getMaintenanceDocumentService().setupNewMaintenanceDocument(BalanceTransfer.class.getName(), 372 "BalanceTransferDocumentType",KRADConstants.MAINTENANCE_NEW_ACTION); 373 374 String personName = (principalName != null && principalName.getDefaultName() != null) ? principalName.getDefaultName().getCompositeName() : StringUtils.EMPTY; 375 String date = TKUtils.formatDate(balanceTransfer.getEffectiveLocalDate()); 376 document.getDocumentHeader().setDocumentDescription(personName + " (" + balanceTransfer.getPrincipalId() + ") - " + date); 377 Map<String,String[]> params = new HashMap<String,String[]>(); 378 379 KRADServiceLocatorWeb.getMaintenanceDocumentService().setupMaintenanceObject(document, KRADConstants.MAINTENANCE_NEW_ACTION, params); 380 BalanceTransfer btObj = (BalanceTransfer) document.getNewMaintainableObject().getDataObject(); 381 382 btObj.setAccrualCategoryRule(balanceTransfer.getAccrualCategoryRule()); 383 btObj.setEffectiveDate(balanceTransfer.getEffectiveDate()); 384 btObj.setForfeitedAmount(balanceTransfer.getForfeitedAmount()); 385 btObj.setFromAccrualCategory(balanceTransfer.getFromAccrualCategory()); 386 btObj.setPrincipalId(balanceTransfer.getPrincipalId()); 387 btObj.setToAccrualCategory(balanceTransfer.getToAccrualCategory()); 388 btObj.setTransferAmount(balanceTransfer.getTransferAmount()); 389 btObj.setAmountTransferred(balanceTransfer.getAmountTransferred()); 390 btObj.setSstoId(balanceTransfer.getSstoId()); 391 btObj.setDocumentHeaderId(document.getDocumentHeader().getWorkflowDocument().getDocumentId()); 392 //LmServiceLocator.getBalanceTransferService().saveOrUpdate(btObj); 393 document.getNewMaintainableObject().setDataObject(btObj); 394 try { 395 KRADServiceLocatorWeb.getDocumentService().saveDocument(document); 396 } catch (WorkflowException e) { 397 // TODO Auto-generated catch block 398 Assert.fail("Caught workflow exception while saving document"); 399 } 400 document.getDocumentHeader().getWorkflowDocument().saveDocument(""); 401 402 balanceTransfer = LmServiceLocator.getBalanceTransferService().transfer(btObj); 403 404 }*/ 405 406 }