001 /* 002 * Copyright 2011 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.kfs.fp.document.validation.impl; 017 018 import java.util.HashMap; 019 import java.util.Map; 020 021 import org.apache.commons.lang.StringUtils; 022 import org.kuali.kfs.coa.businessobject.Account; 023 import org.kuali.kfs.coa.businessobject.SubAccount; 024 import org.kuali.kfs.coa.businessobject.SubObjectCode; 025 import org.kuali.kfs.fp.businessobject.CreditCardVendor; 026 import org.kuali.kfs.sys.KFSKeyConstants; 027 import org.kuali.rice.kns.document.MaintenanceDocument; 028 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 029 import org.kuali.rice.kns.util.ObjectUtils; 030 031 /** 032 * This class represents business rules for the credit card vendor maintenance document 033 */ 034 public class CreditCardVendorRule extends MaintenanceDocumentRuleBase { 035 036 protected CreditCardVendor newCreditCardVendor; 037 038 /** 039 * Sets up a CreditCardVendor convenience objects to make sure all possible sub-objects are populated 040 * 041 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects() 042 */ 043 public void setupConvenienceObjects() { 044 045 newCreditCardVendor = (CreditCardVendor) super.getNewBo(); 046 } 047 048 /** 049 * Return true if rules for processing a save for the credit card maintenance document are are valid. 050 * 051 * @param document maintenance document 052 * @return true credit card vendor number is valid 053 * 054 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 055 */ 056 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) { 057 // default to success 058 boolean success = true; 059 setupConvenienceObjects(); 060 061 // check valid Credit Card Vendor Number (numeric, minimum length) 062 success &= checkCreditCardVendorNumber(); 063 064 return success; 065 } 066 067 /** 068 * Returns value from processCustomRouteDocumentBusinessRules(document) 069 * 070 * @param document maintenance document 071 * @return value from processCustomRouteDocumentBusinessRules(document) 072 * 073 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 074 */ 075 protected boolean processCustomApproveDocumentBusinessRules(MaintenanceDocument document) { 076 077 return processCustomRouteDocumentBusinessRules(document); 078 } 079 080 /** 081 * Returns true credit card vendor maintenance document is routed successfully 082 * 083 * @param document submitted credit card maintenance document 084 * @return true if credit card vendor number, income/expense account numbers, income/expense sub-account numbers, and income/expense sub-object codes are valid 085 * 086 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 087 */ 088 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { 089 // default to success 090 boolean success = true; 091 092 setupConvenienceObjects(); 093 094 // check valid Credit Card Vendor Number (numeric, minimum length) 095 success &= checkCreditCardVendorNumber(); 096 097 // check Income Account Number business rule 098 if (newCreditCardVendor.getIncomeAccountNumber() != null) { 099 success &= checkExistingActiveAccount(newCreditCardVendor.getIncomeAccountNumber(), "incomeAccountNumber", "Income Account Number"); 100 } 101 102 // check Expense Account Number business rule 103 if (newCreditCardVendor.getExpenseAccountNumber() != null) { 104 success &= checkExistingActiveAccount(newCreditCardVendor.getExpenseAccountNumber(), "expenseAccountNumber", "Expense Account Number"); 105 } 106 107 // check Income Sub-Account business rule 108 if (newCreditCardVendor.getIncomeSubAccountNumber() != null) { 109 110 // check required fields to validate Sub-Account 111 if (checkRequiredSubAccount("Income")) { 112 SubAccount existenceSubAccount = checkExistenceSubAccount("Income"); 113 114 // check existence of Sub-Account 115 if (existenceSubAccount == null) { 116 putFieldError("incomeSubAccountNumber", KFSKeyConstants.ERROR_CCV_INVALIDSUBACCOUNT, "Income Sub-Account Number, " + newCreditCardVendor.getIncomeSubAccountNumber()); 117 } 118 else 119 120 // check the Sub-Account is active 121 if (!existenceSubAccount.isActive()) { 122 putFieldError("incomeSubAccountNumber", KFSKeyConstants.ERROR_INACTIVE, "Income Sub-Account"); 123 } 124 } 125 } 126 127 // check Expense Sub-Account business rule 128 if (newCreditCardVendor.getExpenseSubAccountNumber() != null) { 129 if (checkRequiredSubAccount("Expense")) { 130 131 // check existence of Sub-Account 132 SubAccount existenceSubAccount = checkExistenceSubAccount("Expense"); 133 if (existenceSubAccount == null) { 134 putFieldError("expenseSubAccountNumber", KFSKeyConstants.ERROR_CCV_INVALIDSUBACCOUNT, "Expense Sub-Account Number, " + newCreditCardVendor.getExpenseSubAccountNumber()); 135 136 } 137 else 138 139 // check the Sub-Account is active 140 if (!existenceSubAccount.isActive()) { 141 putFieldError("expenseSubAccountNumber", KFSKeyConstants.ERROR_INACTIVE, "Expense Sub-Account"); 142 } 143 } 144 } 145 146 // check Income Sub-Object Code business rule 147 if (newCreditCardVendor.getIncomeFinancialSubObjectCode() != null) { 148 if (checkRequiredSubObjectCode("Income")) { 149 150 // check existence of Sub-Object 151 SubObjectCode existenceSubObj = checkExistenceSubObj("Income"); 152 if (existenceSubObj == null) { 153 putFieldError("incomeFinancialSubObjectCode", KFSKeyConstants.ERROR_CCV_INVALIDSUBOBJECT, "Income Sub-Object Code, " + newCreditCardVendor.getIncomeFinancialSubObjectCode()); 154 } 155 else 156 // check the Sub-Object is active 157 if (!existenceSubObj.isActive()) { 158 putFieldError("incomeFinancialSubObjectCode", KFSKeyConstants.ERROR_INACTIVE, "Income Sub-Object"); 159 } 160 161 } 162 } 163 164 // check Expense Sub-Object Code business rule 165 if (newCreditCardVendor.getExpenseFinancialSubObjectCode() != null) { 166 if (checkRequiredSubObjectCode("Expense")) { 167 168 // check existence of Sub-Object 169 SubObjectCode existenceSubObj = checkExistenceSubObj("Expense"); 170 if (existenceSubObj == null) { 171 putFieldError("expenseFinancialSubObjectCode", KFSKeyConstants.ERROR_CCV_INVALIDSUBOBJECT, "Expense Sub-Object Code, " + newCreditCardVendor.getExpenseFinancialSubObjectCode()); 172 } 173 else 174 // check the Sub-Object is active 175 if (!existenceSubObj.isActive()) { 176 putFieldError("expenseFinancialSubObjectCode", KFSKeyConstants.ERROR_INACTIVE, "Expense Sub-Object"); 177 } 178 } 179 } 180 181 182 return success; 183 } 184 185 186 /** 187 * Returns true if credit card vendor number is valid (i.e. numeric and at least 5 digits) 188 * 189 * @return true if credit card vendor number is valid (i.e. numeric and at least 5 digits) 190 */ 191 protected boolean checkCreditCardVendorNumber() { 192 String ccvNumber = newCreditCardVendor.getFinancialDocumentCreditCardVendorNumber(); 193 194 if (ccvNumber == null) { 195 return false; 196 } 197 else if (!StringUtils.isNumeric(ccvNumber)) { 198 putFieldError("financialDocumentCreditCardVendorNumber", KFSKeyConstants.ERROR_NUMERIC, "Vendor Credit Card Number"); 199 return false; 200 } 201 else if (ccvNumber.length() < 5) { 202 String errorMessage[] = null; 203 errorMessage = new String[] { "Vendor Credit Card Number", "5" }; 204 putFieldError("financialDocumentCreditCardVendorNumber", KFSKeyConstants.ERROR_MIN_LENGTH, errorMessage); 205 return false; 206 } 207 208 return true; 209 } 210 211 212 /** 213 * Returns true if account is active (i.e. exists and is not expired or closed) 214 * 215 * @param accountNumber account number 216 * @param fieldName field name to place error for 217 * @param errorMessage error message to display 218 * @return true if account is active (i.e. exists and is not expired or closed) 219 */ 220 protected boolean checkExistingActiveAccount(String accountNumber, String fieldName, String errorMessage) { 221 boolean result = false; 222 Account account; 223 Map pkMap = new HashMap(); 224 pkMap.put("accountNumber", accountNumber); 225 account = (Account) super.getBoService().findByPrimaryKey(Account.class, pkMap); 226 227 // if the object doesnt exist, then we cant continue, so exit 228 if (ObjectUtils.isNull(account)) { 229 putFieldError(fieldName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage); 230 return result; 231 } 232 233 // check whether expired or not 234 if (account.isExpired()) { 235 putFieldError(fieldName, KFSKeyConstants.ERROR_EXPIRED, errorMessage); 236 return result; 237 } 238 239 // check whether closed or not 240 if (!account.isActive()) { 241 putFieldError(fieldName, KFSKeyConstants.ERROR_CLOSED, errorMessage); 242 return result; 243 } 244 245 246 return true; 247 } 248 249 /** 250 * Returns true if income/expense financial chart of accounts code and account number exist. Income or expense is determined by 251 * the "Income" value or the "Expense" value passed in to the method as a string 252 * 253 * @param string determines whether or not to check income or expense sub account information (valid values include "Income" or "Expense") 254 * @return true if corresponding sub account values exist 255 */ 256 protected boolean checkRequiredSubAccount(String string) { 257 boolean returnVal = true; 258 if (string.equals("Income")) { 259 if (newCreditCardVendor.getIncomeFinancialChartOfAccountsCode() == null) { 260 putFieldError("incomeFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBACCOUNT_REQUIRED, "Income Chart"); 261 returnVal = false; 262 } 263 264 if (newCreditCardVendor.getIncomeAccountNumber() == null) { 265 putFieldError("incomeAccountNumber", KFSKeyConstants.ERROR_CCV_INCOME_SUBACCOUNT_REQUIRED, "Income Account Number"); 266 returnVal = false; 267 } 268 } 269 270 271 if (string.equals("Expense")) { 272 if (newCreditCardVendor.getExpenseFinancialChartOfAccountsCode() == null) { 273 putFieldError("expenseFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBACCOUNT_REQUIRED, "Expense Chart"); 274 returnVal = false; 275 } 276 277 if (newCreditCardVendor.getExpenseAccountNumber() == null) { 278 putFieldError("expenseAccountNumber", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBACCOUNT_REQUIRED, "Expense Account Number"); 279 returnVal = false; 280 } 281 } 282 283 284 return returnVal; 285 } 286 287 288 /** 289 * Returns a SubAccount object if SubAccount object exists for "Income" or "Expense" 290 * 291 * @param string determines whether or not to retrieve a income or expense sub account (valid values include "Income" or "Expense") 292 * @return SubAccount Income/Expense SubAccount object 293 */ 294 protected SubAccount checkExistenceSubAccount(String string) { 295 296 SubAccount subAccount = null; 297 298 if (string.equals("Income")) { 299 Map pkMap = new HashMap(); 300 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getIncomeFinancialChartOfAccountsCode()); 301 pkMap.put("accountNumber", newCreditCardVendor.getIncomeAccountNumber()); 302 pkMap.put("subAccountNumber", newCreditCardVendor.getIncomeSubAccountNumber()); 303 subAccount = (SubAccount) super.getBoService().findByPrimaryKey(SubAccount.class, pkMap); 304 } 305 306 if (string.equals("Expense")) { 307 Map pkMap = new HashMap(); 308 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getExpenseFinancialChartOfAccountsCode()); 309 pkMap.put("accountNumber", newCreditCardVendor.getExpenseAccountNumber()); 310 pkMap.put("subAccountNumber", newCreditCardVendor.getExpenseSubAccountNumber()); 311 subAccount = (SubAccount) super.getBoService().findByPrimaryKey(SubAccount.class, pkMap); 312 } 313 314 return subAccount; 315 } 316 317 318 /** 319 * Returns a true sub-object code exists for "Income" or "Expense" 320 * 321 * @param string determines whether or not to check for an income or expense sub-object code (valid values include "Income" or "Expense") 322 * @return true if income/expense chart of account code, account number, and financial object code exist 323 */ 324 protected boolean checkRequiredSubObjectCode(String string) { 325 326 boolean returnVal = true; 327 if (string.equals("Income")) { 328 if (newCreditCardVendor.getIncomeFinancialChartOfAccountsCode() == null) { 329 putFieldError("incomeFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Chart"); 330 returnVal = false; 331 } 332 333 if (newCreditCardVendor.getIncomeAccountNumber() == null) { 334 putFieldError("incomeAccountNumber", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Account Number"); 335 returnVal = false; 336 } 337 338 if (newCreditCardVendor.getIncomeFinancialObjectCode() == null) { 339 putFieldError("incomeFinancialObjectCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Object Code"); 340 returnVal = false; 341 } 342 343 } 344 345 346 if (string.equals("Expense")) { 347 if (newCreditCardVendor.getExpenseFinancialChartOfAccountsCode() == null) { 348 putFieldError("expenseFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Chart"); 349 returnVal = false; 350 } 351 352 if (newCreditCardVendor.getExpenseAccountNumber() == null) { 353 putFieldError("expenseAccountNumber", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Account Number"); 354 returnVal = false; 355 } 356 357 if (newCreditCardVendor.getExpenseFinancialObjectCode() == null) { 358 putFieldError("expenseFinancialObjectCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Object Code"); 359 returnVal = false; 360 } 361 362 } 363 364 365 return returnVal; 366 } 367 368 369 /** 370 * Returns a SubObjCd object if SubObjCd object exists for "Income" or "Expense" 371 * 372 * @param string determines whether or not to retrieve a income or expense sub object (valid values include "Income" or "Expense") 373 * @return SubAccount Income/Expense SubObjCd object 374 */ 375 protected SubObjectCode checkExistenceSubObj(String string) { 376 377 SubObjectCode subObjCd = null; 378 379 if (string.equals("Income")) { 380 Map pkMap = new HashMap(); 381 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getIncomeFinancialChartOfAccountsCode()); 382 pkMap.put("accountNumber", newCreditCardVendor.getIncomeAccountNumber()); 383 pkMap.put("financialObjectCode", newCreditCardVendor.getIncomeFinancialObjectCode()); 384 pkMap.put("financialSubObjectCode", newCreditCardVendor.getIncomeFinancialSubObjectCode()); 385 subObjCd = (SubObjectCode) super.getBoService().findByPrimaryKey(SubObjectCode.class, pkMap); 386 } 387 388 if (string.equals("Expense")) { 389 Map pkMap = new HashMap(); 390 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getExpenseFinancialChartOfAccountsCode()); 391 pkMap.put("accountNumber", newCreditCardVendor.getExpenseAccountNumber()); 392 pkMap.put("financialObjectCode", newCreditCardVendor.getExpenseFinancialObjectCode()); 393 pkMap.put("financialSubObjectCode", newCreditCardVendor.getExpenseFinancialSubObjectCode()); 394 subObjCd = (SubObjectCode) super.getBoService().findByPrimaryKey(SubObjectCode.class, pkMap); 395 } 396 397 return subObjCd; 398 } 399 400 }