001/* 002 * Copyright 2008 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 */ 016package org.kuali.ole.coa.document.validation.impl; 017 018import java.math.BigDecimal; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.commons.lang.StringUtils; 026import org.kuali.ole.coa.businessobject.Account; 027import org.kuali.ole.coa.businessobject.Chart; 028import org.kuali.ole.coa.businessobject.IndirectCostRecoveryRate; 029import org.kuali.ole.coa.businessobject.IndirectCostRecoveryRateDetail; 030import org.kuali.ole.coa.businessobject.ObjectCode; 031import org.kuali.ole.coa.businessobject.SubAccount; 032import org.kuali.ole.coa.businessobject.SubObjectCode; 033import org.kuali.ole.gl.GeneralLedgerConstants; 034import org.kuali.ole.sys.OLEConstants; 035import org.kuali.ole.sys.OLEKeyConstants; 036import org.kuali.ole.sys.OLEPropertyConstants; 037import org.kuali.ole.sys.businessobject.SystemOptions; 038import org.kuali.ole.sys.context.SpringContext; 039import org.kuali.rice.core.api.util.RiceKeyConstants; 040import org.kuali.rice.kns.document.MaintenanceDocument; 041import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 042import org.kuali.rice.kns.service.DataDictionaryService; 043import org.kuali.rice.krad.bo.PersistableBusinessObject; 044import org.kuali.rice.krad.util.GlobalVariables; 045import org.kuali.rice.krad.util.KRADConstants; 046 047 048public class IndirectCostRecoveryRateRule extends MaintenanceDocumentRuleBase { 049 050 protected static final String MAINTAINABLE_DETAIL_ERROR_PATH = KRADConstants.MAINTENANCE_NEW_MAINTAINABLE + "indirectCostRecoveryRateDetails"; 051 protected static final String MAINTAINABLE_DETAIL_ADDLINE_ERROR_PATH = "add.indirectCostRecoveryRateDetails"; 052 053 protected IndirectCostRecoveryRate indirectCostRecoveryRate; 054 protected IndirectCostRecoveryRateDetail indirectCostRecoveryRateDetail; 055 protected List<IndirectCostRecoveryRateDetail> indirectCostRecoveryRateDetails; 056 057 public void setupConvenienceObjects() { 058 indirectCostRecoveryRate = (IndirectCostRecoveryRate) super.getNewBo(); 059 indirectCostRecoveryRateDetails = indirectCostRecoveryRate.getIndirectCostRecoveryRateDetails(); 060 } 061 062 @Override 063 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { 064 boolean success = true; 065 066 BigDecimal awardIndrCostRcvyRatePctCredits = new BigDecimal(0); 067 BigDecimal awardIndrCostRcvyRatePctDebits = new BigDecimal(0); 068 069 if (!processYear()) { 070 success = false; 071 } 072 else { 073 for(int i = 0;i<indirectCostRecoveryRateDetails.size();i++) { 074 if(indirectCostRecoveryRateDetails.get(i).isActive()) { 075 GlobalVariables.getMessageMap().addToErrorPath(MAINTAINABLE_DETAIL_ERROR_PATH + "[" + i + "]"); 076 success &= processCollectionLine(indirectCostRecoveryRateDetails.get(i)); 077 GlobalVariables.getMessageMap().removeFromErrorPath(MAINTAINABLE_DETAIL_ERROR_PATH + "[" + i + "]"); 078 079 if(indirectCostRecoveryRateDetails.get(i).isActive()) { 080 if(OLEConstants.GL_CREDIT_CODE.equals(indirectCostRecoveryRateDetails.get(i).getTransactionDebitIndicator())) { 081 awardIndrCostRcvyRatePctCredits = awardIndrCostRcvyRatePctCredits.add(indirectCostRecoveryRateDetails.get(i).getAwardIndrCostRcvyRatePct()); 082 } 083 if(OLEConstants.GL_DEBIT_CODE.equals(indirectCostRecoveryRateDetails.get(i).getTransactionDebitIndicator())) { 084 awardIndrCostRcvyRatePctDebits = awardIndrCostRcvyRatePctDebits.add(indirectCostRecoveryRateDetails.get(i).getAwardIndrCostRcvyRatePct()); 085 } 086 } 087 } 088 } 089 } 090 success &= checkCreditsAndDebits(awardIndrCostRcvyRatePctCredits, awardIndrCostRcvyRatePctDebits); 091 092 return success; 093 } 094 095 public boolean checkCreditsAndDebits(BigDecimal credits, BigDecimal debits) { 096 boolean success = true; 097 098 // global errors, in KeyConstants or KFSconstants or something, use one for the top of the page (mark doc once) 099 // include the key word active (informing that only active records are considered) 100 if(!(credits.compareTo(debits) == 0)) { 101 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.GLOBAL_ERRORS, OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENTS_NOT_EQUAL, 102 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT)); 103 success = false; 104 } 105 106 return success; 107 } 108 109 @Override 110 public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) { 111 boolean success = true; 112 IndirectCostRecoveryRateDetail item = (IndirectCostRecoveryRateDetail) line; 113 success &= processCollectionLine(item); 114 return success; 115 } 116 117 public boolean processCollectionLine(IndirectCostRecoveryRateDetail item) { 118 boolean success = true; 119 120 success &= validateWildcards(item); 121 if(success) { 122 success &= checkExistence(item) && checkRateFormat(item); 123 } 124 125 return success; 126 } 127 128 public boolean checkExistence(IndirectCostRecoveryRateDetail item) { 129 boolean success = 130 processYear() && 131 processChart(item) && 132 processAccount(item) && 133 processSubAccount(item) && 134 processObjectCode(item) && 135 processSubObjectCode(item); 136 return success; 137 } 138 139 public boolean processYear() { 140 boolean success = true; 141 Map pkMap = new HashMap(); 142 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear(); 143 pkMap.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 144 if(!checkExistenceFromTable(SystemOptions.class, pkMap)) { 145 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE + OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, 146 RiceKeyConstants.ERROR_EXISTENCE, 147 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRate.class, OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR)); 148 success = false; 149 } 150 return success; 151 } 152 153 protected boolean processChart(IndirectCostRecoveryRateDetail item) { 154 boolean success = true; 155 Map pkMap = new HashMap(); 156 String chart = item.getChartOfAccountsCode(); 157 if(StringUtils.isNotBlank(chart)) { 158 if(!propertyIsWildcard(chart)) { 159 pkMap.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart); 160 if(!checkExistenceFromTable(Chart.class, pkMap)) { 161 logErrorUtility(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, RiceKeyConstants.ERROR_EXISTENCE); 162 success = false; 163 } 164 } 165 } 166 return success; 167 } 168 169 protected boolean processAccount(IndirectCostRecoveryRateDetail item) { 170 boolean success = true; 171 Map pkMap = new HashMap(); 172 String chart = item.getChartOfAccountsCode(); 173 String acct = item.getAccountNumber(); 174 if(StringUtils.isNotBlank(acct)) { 175 if(!propertyIsWildcard(chart)) { 176 pkMap.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart); 177 } 178 if(!propertyIsWildcard(acct)) { 179 pkMap.put(OLEPropertyConstants.ACCOUNT_NUMBER, acct); 180 if(!checkExistenceFromTable(Account.class, pkMap)) { 181 logErrorUtility(OLEPropertyConstants.ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE); 182 success = false; 183 } 184 } 185 } 186 return success; 187 } 188 189 protected boolean processSubAccount(IndirectCostRecoveryRateDetail item) { 190 boolean success = true; 191 Map pkMap = new HashMap(); 192 String chart = item.getChartOfAccountsCode(); 193 String acct = item.getAccountNumber(); 194 String subAcct = item.getSubAccountNumber(); 195 if(StringUtils.isNotBlank(subAcct) && !StringUtils.containsOnly(subAcct, "-")) { // if doesn't contain only dashes 196 if(!propertyIsWildcard(chart)) { 197 pkMap.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart); 198 } 199 if(!propertyIsWildcard(acct)) { 200 pkMap.put(OLEPropertyConstants.ACCOUNT_NUMBER, acct); 201 } 202 if(!propertyIsWildcard(subAcct) && StringUtils.isNotBlank(subAcct) && !StringUtils.containsOnly(subAcct, "-")) { 203 pkMap.put(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, subAcct); 204 if(!checkExistenceFromTable(SubAccount.class, pkMap)) { 205 logErrorUtility(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE); 206 success = false; 207 } 208 } 209 } 210 return success; 211 } 212 213 protected boolean processObjectCode(IndirectCostRecoveryRateDetail item) { 214 boolean success = true; 215 Map pkMap = new HashMap(); 216 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear(); 217 String chart = item.getChartOfAccountsCode(); 218 String objCd = item.getFinancialObjectCode(); 219 pkMap.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 220 if(StringUtils.isNotBlank(objCd)) { 221 if(!propertyIsWildcard(chart)) { 222 pkMap.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart); 223 } 224 if(!propertyIsWildcard(objCd)) { 225 pkMap.put(OLEPropertyConstants.FINANCIAL_OBJECT_CODE, objCd); 226 if(!checkExistenceFromTable(ObjectCode.class, pkMap)) { 227 logErrorUtility(OLEPropertyConstants.FINANCIAL_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE); 228 success = false; 229 } 230 } 231 } 232 return success; 233 } 234 235 protected boolean processSubObjectCode(IndirectCostRecoveryRateDetail item) { // chart being a wildcard implies account number being a wildcard, redundant checking? 236 boolean success = true; 237 Map pkMap = new HashMap(); 238 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear(); 239 String chart = item.getChartOfAccountsCode(); 240 String acct = item.getAccountNumber(); 241 String objCd = item.getFinancialObjectCode(); 242 String subObjCd = item.getFinancialSubObjectCode(); 243 if(StringUtils.isNotBlank(subObjCd) && !propertyIsWildcard(subObjCd) && !StringUtils.containsOnly(subObjCd, "-")) { 244 pkMap.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 245 if(!propertyIsWildcard(chart)) { 246 pkMap.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart); 247 } 248 if(!propertyIsWildcard(acct)) { 249 pkMap.put(OLEPropertyConstants.ACCOUNT_NUMBER, acct); 250 } 251 if(!propertyIsWildcard(objCd)) { 252 pkMap.put(OLEPropertyConstants.FINANCIAL_OBJECT_CODE, objCd); 253 } 254 pkMap.put(OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, subObjCd); 255 if(!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(subObjCd) && !checkExistenceFromTable(SubObjectCode.class, pkMap)) { 256 logErrorUtility(OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE); 257 success = false; 258 } 259 } 260 return success; 261 } 262 263 public boolean checkExistenceFromTable(Class clazz, Map fieldValues) { 264 return getBoService().countMatching(clazz, fieldValues) != 0; 265 } 266 267 public boolean validateWildcards(IndirectCostRecoveryRateDetail item) { 268 boolean success = false; 269 if(!itemUsesWildcard(item) || (itemUsesWildcard(item) && itemPassesWildcardRules(item))) { 270 success = true; 271 } 272 return success; 273 } 274 275 public boolean itemPassesWildcardRules(IndirectCostRecoveryRateDetail item) { 276 boolean success = false; 277 String[] wildcards = {GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY, GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT}; 278 279 success = !itemUsesWildcard(item) || checkWildcardRules(item); 280 281 return success; 282 } 283 284 public boolean itemUsesWildcard(IndirectCostRecoveryRateDetail item) { 285 boolean success = false; 286 String chart = item.getChartOfAccountsCode(); 287 String acct = item.getAccountNumber(); 288 String subAcct = item.getSubAccountNumber(); 289 String objCd = item.getFinancialObjectCode(); 290 String subObjCd = item.getFinancialSubObjectCode(); 291 String[] fields = {chart,acct,subAcct,objCd,subObjCd}; 292 293 for(int i=0;i<fields.length;i++) { 294 success |= propertyIsWildcard(fields[i]); 295 } 296 297 return success; 298 } 299 300 public boolean propertyIsWildcard(String property) { 301 return GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(property) || GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(property); 302 } 303 304 protected boolean checkAccountNumberWildcardRules(IndirectCostRecoveryRateDetail item) { 305 String accountNumber = item.getAccountNumber(); 306 boolean success = true; 307 if (!accountNumber.equals(item.getChartOfAccountsCode())) { 308 GlobalVariables.getMessageMap().putError( 309 OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, 310 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 311 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER), 312 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE) 313 ); 314 success = false; 315 } 316 317 String subAccountNumber = item.getSubAccountNumber(); 318 319 // If # is entered on account, then # "must" be entered for chart and sub account "must" be dashes. 320 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(accountNumber)) { 321 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(item.getChartOfAccountsCode()) && !StringUtils.containsOnly(subAccountNumber, OLEConstants.DASH)) { 322 GlobalVariables.getMessageMap().putError( 323 OLEPropertyConstants.SUB_ACCOUNT_NUMBER, 324 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_FIELD_MUST_BE_DASHES, 325 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER), 326 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT, 327 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.SUB_ACCOUNT_NUMBER)); 328 success = false; 329 } 330 } 331 332 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(accountNumber)) { 333 if (!(StringUtils.equals(GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY, subAccountNumber) || !StringUtils.containsOnly(subAccountNumber, OLEConstants.DASH))) { 334 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, 335 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_ACCOUNT_USE_EXPENDITURE_ENTRY_WILDCARD_RESTRICTION_ON_SUB_ACCOUNT); 336 success = false; 337 } 338 } 339 return success; 340 } 341 342 protected boolean checkAccountNumberNotWildcardRules(IndirectCostRecoveryRateDetail item) { 343 boolean success = true; 344 if (propertyIsWildcard(item.getSubAccountNumber())) { 345 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(item.getSubAccountNumber())) { 346 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_CANNOT_BE_WILDCARD, 347 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.SUB_ACCOUNT_NUMBER), 348 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER)); 349 success = false; 350 } 351 } 352 return success; 353 } 354 355 protected boolean checkObjectCodeWildcardRules(IndirectCostRecoveryRateDetail item) { 356 String financialObjectCode = item.getFinancialObjectCode(); 357 boolean success = true; 358 if (propertyIsWildcard(financialObjectCode)) { 359 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(financialObjectCode)) { 360 GlobalVariables.getMessageMap().putError( 361 OLEPropertyConstants.FINANCIAL_OBJECT_CODE, 362 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID, 363 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT, 364 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_OBJECT_CODE), 365 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY 366 ); 367 success = false; 368 } 369 else { 370 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) { 371 GlobalVariables.getMessageMap().putError( 372 OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, 373 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 374 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_OBJECT_CODE), 375 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE) 376 ); 377 success = false; 378 } 379 } 380 } 381 return success; 382 } 383 384 protected boolean checkSubObjectWildcardRules(IndirectCostRecoveryRateDetail item) { 385 String financialSubObjectCode = item.getFinancialSubObjectCode(); 386 boolean success = true; 387 if (propertyIsWildcard(financialSubObjectCode)) { 388 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(financialSubObjectCode)) { 389 GlobalVariables.getMessageMap().putError( 390 OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, 391 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID, 392 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT, 393 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE), 394 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY 395 ); 396 success = false; 397 } 398 else { 399 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) { 400 GlobalVariables.getMessageMap().putError( 401 OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, 402 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 403 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE), 404 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE) 405 ); 406 success = false; 407 } 408 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getAccountNumber())) { 409 GlobalVariables.getMessageMap().putError( 410 OLEPropertyConstants.ACCOUNT_NUMBER, 411 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 412 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE), 413 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER) 414 ); 415 success = false; 416 } 417 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getFinancialObjectCode())) { 418 GlobalVariables.getMessageMap().putError( 419 OLEPropertyConstants.FINANCIAL_OBJECT_CODE, 420 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 421 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE), 422 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_OBJECT_CODE) 423 ); 424 success = false; 425 } 426 } 427 } 428 return success; 429 } 430 431 protected boolean checkSubAccountWildcardRules(IndirectCostRecoveryRateDetail item) { 432 boolean success = true; 433 String subAccountNumber = item.getSubAccountNumber(); 434 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(subAccountNumber)) { 435 GlobalVariables.getMessageMap().putError( 436 OLEPropertyConstants.SUB_ACCOUNT_NUMBER, 437 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID, 438 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT, 439 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.SUB_ACCOUNT_NUMBER), 440 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY 441 ); 442 success = false; 443 } 444 else { 445 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) { 446 GlobalVariables.getMessageMap().putError( 447 OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, 448 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 449 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.SUB_ACCOUNT_NUMBER), 450 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE) 451 ); 452 success = false; 453 } 454 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getAccountNumber())) { 455 GlobalVariables.getMessageMap().putError( 456 OLEPropertyConstants.ACCOUNT_NUMBER, 457 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH, 458 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.SUB_ACCOUNT_NUMBER), 459 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER) 460 ); 461 success = false; 462 } 463 464 } 465 return success; 466 } 467 468 /* 469 ** If @ is entered on chart, then @ "must" be entered for account and the sub account "must" be either @ or dashes. 470 ** If @ is entered on account, then @ "must" be entered for chart and "may" be entered for sub account. 471 ** If @ is entered on sub account, then @ "must" be entered for chart and account. 472 ** If @ is entered on object code, then @ "must" be entered for chart and "may" be entered for account, sub account and sub object. 473 * (This rule is the murkiest as enter @ in account, sub account, and sub object kicks of some of the other rules in this section). 474 ** If @ is entered on sub object code, then @ "must" be entered for chart, account, and object code and "may" be entered for sub account. 475 476 ** If # is entered on chart, then # "must" be entered for account and sub account "must" be dashes. 477 ** If # is entered on account, then # "must" be entered for chart and sub account "must" be dashes. 478 ** # can not be entered on the sub account. 479 ** # can not be entered on the object code. 480 ** # can not be entered on the sub object code. 481 * 482 */ 483 484 public boolean checkWildcardRules(IndirectCostRecoveryRateDetail item) { 485 boolean success = checkAtMostOneWildcardUsed(item); 486 if (success) { 487 if (propertyIsWildcard(item.getFinancialObjectCode())) { 488 success &= checkObjectCodeWildcardRules(item); // verified 489 } 490 else { 491 } 492 if (propertyIsWildcard(item.getAccountNumber())) { 493 success &= checkAccountNumberWildcardRules(item); // verified 494 } 495 else { 496 success &= checkAccountNumberNotWildcardRules(item); 497 } 498 if (propertyIsWildcard(item.getFinancialSubObjectCode())) { 499 success &= checkSubObjectWildcardRules(item); // verified 500 } 501 502 if (propertyIsWildcard(item.getSubAccountNumber())) { 503 success &= checkSubAccountWildcardRules(item); // verified 504 } 505 506 if (!(propertyIsWildcard(item.getFinancialObjectCode()) || propertyIsWildcard(item.getAccountNumber()))) { 507 // chart code can't be the only wildcard on the item 508 if (success && propertyIsWildcard(item.getChartOfAccountsCode())) { 509 success = false; 510 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_CHART_CODE_NOT_ONLY_WILDCARD, 511 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE), 512 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.ACCOUNT_NUMBER), 513 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, OLEPropertyConstants.FINANCIAL_OBJECT_CODE)); 514 } 515 } 516 } 517 return success; 518 } 519 520 protected boolean checkAtMostOneWildcardUsed(IndirectCostRecoveryRateDetail item) { 521 String chart = item.getChartOfAccountsCode(); 522 String acct = item.getAccountNumber(); 523 String subAcct = item.getSubAccountNumber(); 524 String objCd = item.getFinancialObjectCode(); 525 String subObjCd = item.getFinancialSubObjectCode(); 526 527 boolean success = true; 528 String errorPropertyName = null; 529 530 Set<String> wildcards = new HashSet<String>(); 531 if (propertyIsWildcard(chart)) { 532 wildcards.add(chart); 533 errorPropertyName = OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE; 534 } 535 if (success && propertyIsWildcard(acct)) { 536 wildcards.add(acct); 537 if (wildcards.size() > 1) { 538 success = false; 539 errorPropertyName = OLEPropertyConstants.ACCOUNT_NUMBER; 540 } 541 } 542 if (success && propertyIsWildcard(subAcct)) { 543 wildcards.add(subAcct); 544 if (wildcards.size() > 1) { 545 success = false; 546 errorPropertyName = OLEPropertyConstants.SUB_ACCOUNT_NUMBER; 547 } 548 } 549 if (success && propertyIsWildcard(objCd)) { 550 wildcards.add(objCd); 551 if (wildcards.size() > 1) { 552 success = false; 553 errorPropertyName = OLEPropertyConstants.FINANCIAL_OBJECT_CODE; 554 } 555 } 556 if (success && propertyIsWildcard(subObjCd)) { 557 wildcards.add(subObjCd); 558 if (wildcards.size() > 1) { 559 success = false; 560 errorPropertyName = OLEPropertyConstants.FINANCIAL_SUB_OBJECT_CODE; 561 } 562 } 563 564 if (!success) { 565 GlobalVariables.getMessageMap().putError( 566 errorPropertyName, 567 OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_MULTIPLE_WILDCARDS_ON_ITEM); 568 } 569 return success; 570 } 571 572 public boolean checkRateFormat(IndirectCostRecoveryRateDetail item) { 573 boolean success = true; 574 BigDecimal zero = new BigDecimal(0.00); 575 if(!(item.getAwardIndrCostRcvyRatePct() == null)) { 576 if(item.getAwardIndrCostRcvyRatePct().scale() > 3) { 577 logErrorUtility(OLEPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT, OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENT_INVALID_FORMAT_SCALE); 578 success = false; 579 } 580 if(item.getAwardIndrCostRcvyRatePct().compareTo(zero) < 0) { 581 logErrorUtility(OLEPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT, OLEKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENT_INVALID_FORMAT_ZERO); 582 success = false; 583 } 584 } else { 585 586 } 587 return success; 588 } 589 590 public void logErrorUtility(String propertyName, String errorKey) { 591 GlobalVariables.getMessageMap().putError(propertyName, errorKey, SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, propertyName)); 592 } 593 594}