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.gl.batch.service.impl; 017 018 import java.io.File; 019 import java.io.FilenameFilter; 020 import java.math.BigDecimal; 021 import java.util.HashMap; 022 import java.util.Iterator; 023 import java.util.LinkedHashMap; 024 import java.util.List; 025 import java.util.Map; 026 027 import org.apache.commons.lang.StringUtils; 028 import org.kuali.kfs.gl.GeneralLedgerConstants; 029 import org.kuali.kfs.gl.batch.PosterBalancingStep; 030 import org.kuali.kfs.gl.batch.service.BalancingService; 031 import org.kuali.kfs.gl.batch.service.PosterService; 032 import org.kuali.kfs.gl.businessobject.AccountBalance; 033 import org.kuali.kfs.gl.businessobject.AccountBalanceHistory; 034 import org.kuali.kfs.gl.businessobject.Balance; 035 import org.kuali.kfs.gl.businessobject.BalanceHistory; 036 import org.kuali.kfs.gl.businessobject.Encumbrance; 037 import org.kuali.kfs.gl.businessobject.EncumbranceHistory; 038 import org.kuali.kfs.gl.businessobject.Entry; 039 import org.kuali.kfs.gl.businessobject.EntryHistory; 040 import org.kuali.kfs.gl.businessobject.LedgerBalanceHistory; 041 import org.kuali.kfs.gl.businessobject.OriginEntryFull; 042 import org.kuali.kfs.gl.businessobject.OriginEntryInformation; 043 import org.kuali.kfs.gl.dataaccess.AccountBalanceDao; 044 import org.kuali.kfs.gl.dataaccess.BalancingDao; 045 import org.kuali.kfs.gl.dataaccess.EncumbranceDao; 046 import org.kuali.kfs.sys.FileUtil; 047 import org.kuali.kfs.sys.KFSConstants; 048 import org.kuali.kfs.sys.KFSKeyConstants; 049 import org.kuali.kfs.sys.KFSPropertyConstants; 050 import org.kuali.kfs.sys.Message; 051 import org.kuali.rice.kns.util.KualiDecimal; 052 import org.kuali.rice.kns.util.ObjectUtils; 053 import org.springframework.transaction.annotation.Transactional; 054 055 /** 056 * Service implementation of BalancingService of GL balancing 057 */ 058 @Transactional 059 public class BalancingServiceImpl extends BalancingServiceBaseImpl<EntryHistory, BalanceHistory> implements BalancingService { 060 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalancingServiceImpl.class); 061 062 protected BalancingDao balancingDao; 063 protected AccountBalanceDao accountBalanceDao; 064 protected EncumbranceDao encumbranceDao; 065 066 protected File posterInputFile = null; 067 protected File posterErrorOutputFile = null; 068 069 protected File reversalInputFile = null; 070 protected File reversalErrorOutputFile = null; 071 072 protected File icrInputFile = null; 073 protected File icrErrorOutputFile = null; 074 075 076 @Override 077 public boolean runBalancing() { 078 // clear out the file cache, otherwise, it won't update the history tables with the latest poster files 079 // therefore, it will use the files that were first used when the balancing job was run when the JVM started, and that'll cause out of balance errors 080 clearPosterFileCache(); 081 return super.runBalancing(); 082 } 083 084 /** 085 * @see org.kuali.kfs.gl.batch.service.BalancingService#getPosterInputFile() 086 */ 087 public File getPosterInputFile() { 088 // avoid running scanning logic on file system 089 if (posterInputFile != null) { 090 return posterInputFile; 091 } 092 return posterInputFile = getFile( 093 GeneralLedgerConstants.BatchFileSystem.POSTER_INPUT_FILE, 094 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 095 } 096 097 /** 098 * @see org.kuali.kfs.gl.batch.service.BalancingService#getPosterErrorOutputFile() 099 */ 100 public File getPosterErrorOutputFile() { 101 // avoid running scanning logic on file system 102 if (posterErrorOutputFile != null) { 103 return posterErrorOutputFile; 104 } 105 return posterErrorOutputFile = getFile( 106 GeneralLedgerConstants.BatchFileSystem.POSTER_ERROR_OUTPUT_FILE, 107 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 108 } 109 110 /** 111 * @see org.kuali.kfs.gl.batch.service.BalancingService#getReversalInputFile() 112 */ 113 public File getReversalInputFile(){ 114 if (reversalInputFile != null) { 115 return reversalInputFile; 116 } 117 return reversalInputFile = getFile( 118 GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_VALID_OUTPUT_FILE, 119 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 120 } 121 122 /** 123 * @see org.kuali.kfs.gl.batch.service.BalancingService#getReversalErrorOutputFile() 124 */ 125 public File getReversalErrorOutputFile(){ 126 if (reversalErrorOutputFile != null) { 127 return reversalErrorOutputFile; 128 } 129 return reversalErrorOutputFile = getFile( 130 GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_ERROR_OUTPUT_FILE, 131 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 132 } 133 134 /** 135 * @see org.kuali.kfs.gl.batch.service.BalancingService#getICRInputFile() 136 */ 137 public File getICRInputFile(){ 138 if (icrInputFile != null) { 139 return icrInputFile; 140 } 141 return icrInputFile = getFile( 142 GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_INPUT_FILE, 143 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 144 } 145 146 /** 147 * @see org.kuali.kfs.gl.batch.service.BalancingService#getICRErrorOutputFile() 148 */ 149 public File getICRErrorOutputFile(){ 150 if (icrErrorOutputFile != null) { 151 return icrErrorOutputFile; 152 } 153 return icrErrorOutputFile = getFile( 154 GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_ERROR_OUTPUT_FILE, 155 GeneralLedgerConstants.BatchFileSystem.EXTENSION); 156 } 157 158 public File getFile(final String fileName, final String fileExtension){ 159 FilenameFilter filenameFilter = new FilenameFilter() { 160 public boolean accept(File dir, String name) { 161 return (name.startsWith(fileName) && name.endsWith(fileExtension)); 162 } 163 }; 164 return FileUtil.getNewestFile(new File(batchFileDirectoryName), filenameFilter); 165 } 166 167 /** 168 * @see org.kuali.kfs.gl.batch.service.BalancingService#getPastFiscalYearsToConsider() 169 */ 170 public int getPastFiscalYearsToConsider() { 171 return Integer.parseInt(parameterService.getParameterValue(PosterBalancingStep.class, GeneralLedgerConstants.Balancing.NUMBER_OF_PAST_FISCAL_YEARS_TO_INCLUDE)); 172 } 173 174 /** 175 * @see org.kuali.kfs.gl.batch.service.BalancingService#getComparisonFailuresToPrintPerReport() 176 */ 177 public int getComparisonFailuresToPrintPerReport() { 178 return Integer.parseInt(parameterService.getParameterValue(PosterBalancingStep.class, GeneralLedgerConstants.Balancing.NUMBER_OF_COMPARISON_FAILURES_TO_PRINT_PER_REPORT)); 179 } 180 181 /** 182 * @see org.kuali.kfs.gl.batch.service.BalancingService#getShortTableLabel(java.lang.String) 183 */ 184 public String getShortTableLabel(String businessObjectName) { 185 Map<String, String> names = new HashMap<String, String>(); 186 names.put((Entry.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENTRY_LABEL)); 187 names.put((EntryHistory.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENTRY_LABEL)); 188 names.put((Balance.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_BALANCE_LABEL)); 189 names.put((BalanceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_BALANCE_LABEL)); 190 names.put((AccountBalance.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_LABEL)); 191 names.put((AccountBalanceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_LABEL)); 192 names.put((Encumbrance.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_LABEL)); 193 names.put((EncumbranceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_LABEL)); 194 195 return names.get(businessObjectName) == null ? kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_UNKNOWN_LABEL) : names.get(businessObjectName); 196 } 197 198 /** 199 * @see org.kuali.kfs.gl.batch.service.BalancingService#getOriginEntry(java.lang.String, int) 200 */ 201 public OriginEntryInformation getOriginEntry(String inputLine, int lineNumber) { 202 // We need a OriginEntryFull because that's what updateBalanceHistory is looking for 203 OriginEntryFull originEntry = new OriginEntryFull(); 204 originEntry.setFromTextFileForBatch(inputLine, lineNumber); 205 206 return originEntry; 207 } 208 209 /** 210 * @see org.kuali.kfs.gl.batch.service.BalancingService#updateEntryHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) 211 * @see org.kuali.kfs.gl.batch.service.impl.PostEntry#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 212 */ 213 public void updateEntryHistory(Integer postMode, OriginEntryInformation originEntry) { 214 // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? 215 EntryHistory entryHistory = new EntryHistory(originEntry); 216 217 EntryHistory retrievedEntryHistory = (EntryHistory) businessObjectService.retrieve(entryHistory); 218 if(ObjectUtils.isNotNull(retrievedEntryHistory)) { 219 entryHistory = retrievedEntryHistory; 220 } 221 222 entryHistory.addAmount(originEntry.getTransactionLedgerEntryAmount()); 223 224 businessObjectService.save(entryHistory); 225 } 226 227 /** 228 * @see org.kuali.kfs.gl.batch.service.BalancingService#updateBalanceHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) 229 * @see org.kuali.kfs.gl.batch.service.impl.PostBalance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 230 */ 231 public void updateBalanceHistory(Integer postMode, OriginEntryInformation originEntry) { 232 // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? 233 OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; 234 BalanceHistory balanceHistory = new BalanceHistory(originEntryFull); 235 236 BalanceHistory retrievedBalanceHistory = (BalanceHistory) businessObjectService.retrieve(balanceHistory); 237 if(ObjectUtils.isNotNull(retrievedBalanceHistory)) { 238 balanceHistory = retrievedBalanceHistory; 239 } 240 241 KualiDecimal amount = originEntryFull.getTransactionLedgerEntryAmount(); 242 243 // Make sure the amount update properly recognized debit / credit logic. This is modeled after PostBalance#post 244 originEntryFull.refreshReferenceObject(KFSPropertyConstants.BALANCE_TYPE); 245 originEntryFull.refreshReferenceObject(KFSPropertyConstants.OBJECT_TYPE); 246 if (originEntryFull.getBalanceType().isFinancialOffsetGenerationIndicator()) { 247 if (!originEntryFull.getTransactionDebitCreditCode().equals(originEntryFull.getObjectType().getFinObjectTypeDebitcreditCd())) { 248 amount = amount.negated(); 249 } 250 } 251 252 balanceHistory.addAmount(originEntryFull.getUniversityFiscalPeriodCode(), amount); 253 254 businessObjectService.save(balanceHistory); 255 } 256 257 /** 258 * @see org.kuali.kfs.gl.batch.service.BalancingService#getBalance(org.kuali.kfs.gl.businessobject.LedgerBalanceHistory) 259 */ 260 public Balance getBalance(LedgerBalanceHistory ledgerBalanceHistory) { 261 Balance balance = new Balance((BalanceHistory) ledgerBalanceHistory); 262 return (Balance) businessObjectService.retrieve(balance); 263 } 264 265 /** 266 * @see org.kuali.kfs.gl.batch.service.BalancingService#clearPosterFileCache() 267 */ 268 public void clearPosterFileCache() { 269 this.posterInputFile = null; 270 this.posterErrorOutputFile = null; 271 } 272 273 /** 274 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customPopulateHistoryTables(java.lang.Integer) 275 */ 276 @Override 277 public void customPopulateHistoryTables(Integer fiscalYear) { 278 balancingDao.populateAccountBalancesHistory(fiscalYear); 279 balancingDao.populateEncumbranceHistory(fiscalYear); 280 } 281 282 /** 283 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#doesCustomHistoryExist(java.lang.Integer) 284 */ 285 @Override 286 protected boolean doesCustomHistoryExist(Integer fiscalYear) { 287 return (this.getHistoryCount(fiscalYear, AccountBalanceHistory.class) > 0 && 288 this.getHistoryCount(fiscalYear, EncumbranceHistory.class) > 0); 289 } 290 291 /** 292 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#deleteCustomHistory(java.lang.Integer) 293 */ 294 @Override 295 protected void deleteCustomHistory(Integer fiscalYear) { 296 deleteHistory(fiscalYear, AccountBalanceHistory.class); 297 deleteHistory(fiscalYear, EncumbranceHistory.class); 298 299 reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_OBSOLETE_FISCAL_YEAR_DATA_DELETED), (AccountBalanceHistory.class).getSimpleName(), (EncumbranceHistory.class).getSimpleName(), fiscalYear); 300 reportWriterService.writeNewLines(1); 301 } 302 303 /** 304 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#updateCustomHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) 305 */ 306 @Override 307 protected void updateCustomHistory(Integer postMode, OriginEntryInformation originEntry) { 308 this.updateAccountBalanceHistory(originEntry); 309 this.updateEncumbranceHistory(originEntry); 310 } 311 312 313 /** 314 * Update the account balance history table 315 * @param originEntry representing the update details 316 * @see org.kuali.kfs.gl.batch.service.impl.PostAccountBalance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 317 */ 318 protected void updateAccountBalanceHistory(OriginEntryInformation originEntry) { 319 OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; 320 321 // As taken from PostAccountBalance#post: only post transactions where: balance type code is AC or CB or where object type isn't FB and 322 // balance type code is EX, IE, PE and CE 323 originEntryFull.refreshReferenceObject(KFSPropertyConstants.OPTION); 324 if ((originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getActualFinancialBalanceTypeCd()) || originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getBudgetCheckingBalanceTypeCd())) || (originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getExtrnlEncumFinBalanceTypCd()) || originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getIntrnlEncumFinBalanceTypCd()) || originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getPreencumbranceFinBalTypeCd()) || originEntryFull.getFinancialBalanceTypeCode().equals(originEntryFull.getOption().getCostShareEncumbranceBalanceTypeCd())) && (!originEntryFull.getFinancialObjectTypeCode().equals(originEntryFull.getOption().getFinObjectTypeFundBalanceCd()))) { 325 // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? 326 AccountBalanceHistory accountBalanceHistory = new AccountBalanceHistory(originEntry); 327 328 AccountBalanceHistory retrievedAccountBalanceHistory = (AccountBalanceHistory) businessObjectService.retrieve(accountBalanceHistory); 329 if(ObjectUtils.isNotNull(retrievedAccountBalanceHistory)) { 330 accountBalanceHistory = retrievedAccountBalanceHistory; 331 } 332 333 // Following is a copy of PostAccountBalance.updateAccountBalanceReturn since the blancing process is to do this independently 334 if (accountBalanceHistory.addAmount(originEntryFull)) { 335 businessObjectService.save(accountBalanceHistory); 336 } 337 } 338 } 339 340 /** 341 * 342 * @see org.kuali.kfs.gl.batch.service.BalancingService#clearBalanceHistory() 343 */ 344 345 public void clearHistories() { 346 Map<String, Object> fieldValues = new HashMap<String, Object>(); 347 businessObjectService.deleteMatching(EntryHistory.class, fieldValues); 348 businessObjectService.deleteMatching(BalanceHistory.class, fieldValues); 349 businessObjectService.deleteMatching(EncumbranceHistory.class, fieldValues); 350 businessObjectService.deleteMatching(AccountBalanceHistory.class, fieldValues); 351 352 reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_HISTORY_PURGED)); 353 354 355 } 356 357 /** 358 * Compares entries in the Balance and BalanceHistory tables to ensure the amounts match. 359 * @return count is compare failures 360 */ 361 protected Integer compareBalanceHistory() { 362 Integer countComparisionFailures = 0; 363 364 List data = ledgerEntryBalanceCachingDao.compareBalanceHistory(Balance.class, balanceHistoryPersistentClass, getPastFiscalYearsToConsider()); 365 366 if (!data.isEmpty()) { 367 for (Iterator itr = data.iterator(); itr.hasNext();) { 368 BalanceHistory balance = createBalanceFromMap((Map)itr.next()); 369 countComparisionFailures++; 370 if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { 371 reportWriterService.writeError(balance, new Message(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, balance.getClass().getSimpleName())); 372 } 373 } 374 } 375 376 return countComparisionFailures; 377 } 378 379 /** 380 * Compares entries in the Entry and EntryHistory tables to ensure the amounts match. 381 * @return count is compare failures 382 */ 383 protected Integer compareEntryHistory() { 384 Integer countComparisionFailures = 0; 385 386 List data = ledgerEntryBalanceCachingDao.compareEntryHistory(Entry.class, entryHistoryPersistentClass, getPastFiscalYearsToConsider()); 387 388 if (!data.isEmpty()) { 389 for (Iterator itr = data.iterator(); itr.hasNext();) { 390 EntryHistory entry = createEntryHistoryFromMap((Map)itr.next()); 391 countComparisionFailures++; 392 if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { 393 reportWriterService.writeError(entry, new Message(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, entry.getClass().getSimpleName())); 394 } 395 396 } 397 } 398 399 return countComparisionFailures; 400 } 401 402 /** 403 * Update the encumbrance history table 404 * @param originEntry representing the update details 405 * @see org.kuali.kfs.gl.batch.service.impl.PostEncumbrance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 406 */ 407 protected void updateEncumbranceHistory(OriginEntryInformation originEntry) { 408 OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; 409 410 // PostEncumbrance.verifyTransaction is not run because entries that fail that verification will be in the error poster file which entries 411 // are already ignored before being passed to this method. 412 413 // As taken from PostEncumbrance#post: If the encumbrance update code is space or N, or the object type code is FB we don't need to post an encumbrance 414 originEntryFull.refreshReferenceObject(KFSPropertyConstants.OPTION); 415 if ((StringUtils.isBlank(originEntryFull.getTransactionEncumbranceUpdateCode())) || " ".equals(originEntryFull.getTransactionEncumbranceUpdateCode()) || KFSConstants.ENCUMB_UPDT_NO_ENCUMBRANCE_CD.equals(originEntryFull.getTransactionEncumbranceUpdateCode()) || originEntryFull.getOption().getFinObjectTypeFundBalanceCd().equals(originEntryFull.getFinancialObjectTypeCode())) { 416 return; 417 } 418 419 EncumbranceHistory encumbranceHistory = new EncumbranceHistory(originEntryFull); 420 if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(originEntryFull.getTransactionEncumbranceUpdateCode())) { 421 encumbranceHistory.setDocumentNumber(originEntryFull.getReferenceFinancialDocumentNumber()); 422 encumbranceHistory.setOriginCode(originEntryFull.getReferenceFinancialSystemOriginationCode()); 423 encumbranceHistory.setDocumentTypeCode(originEntryFull.getReferenceFinancialDocumentTypeCode()); 424 } 425 // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? 426 EncumbranceHistory retrievedEncumbranceHistory = (EncumbranceHistory) businessObjectService.retrieve(encumbranceHistory); 427 428 if(ObjectUtils.isNotNull(retrievedEncumbranceHistory)) { 429 encumbranceHistory = retrievedEncumbranceHistory; 430 } 431 432 // Following is a copy & paste of PostEncumbrance.updateEncumbrance since the balancing process is to do this independently 433 encumbranceHistory.addAmount(originEntryFull); 434 435 businessObjectService.save(encumbranceHistory); 436 } 437 438 439 440 /** 441 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customCompareHistory() 442 */ 443 @Override 444 protected Map<String, Integer> customCompareHistory() { 445 Integer countAccountBalanceComparisionFailure = this.accountBalanceCompareHistory(); 446 Integer countEncumbranceComparisionFailure = this.encumbranceCompareHistory(); 447 448 // Using LinkedHashMap because we want it ordered 449 Map<String, Integer> countMap = new LinkedHashMap<String, Integer>(); 450 countMap.put((AccountBalanceHistory.class).getSimpleName(), countAccountBalanceComparisionFailure); 451 countMap.put((EncumbranceHistory.class).getSimpleName(), countEncumbranceComparisionFailure); 452 453 return countMap; 454 } 455 456 /** 457 * Does comparision, error printing and returns failure count for account balances 458 * @return failure count 459 */ 460 protected Integer accountBalanceCompareHistory() { 461 Integer countComparisionFailures = 0; 462 463 List data = ledgerEntryBalanceCachingDao.accountBalanceCompareHistory(AccountBalance.class, AccountBalanceHistory.class, getPastFiscalYearsToConsider()); 464 465 if (!data.isEmpty()) { 466 for (Iterator itr = data.iterator(); itr.hasNext();) { 467 AccountBalanceHistory accountBalanceHistory = createAccountBalanceHistoryFromMap((Map)itr.next()); 468 countComparisionFailures++; 469 if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { 470 reportWriterService.writeError(accountBalanceHistory, new Message(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, accountBalanceHistory.getClass().getSimpleName())); 471 } 472 } 473 474 } else { 475 reportWriterService.writeNewLines(1); 476 reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), (AccountBalanceHistory.class).getSimpleName(), countComparisionFailures, this.getComparisonFailuresToPrintPerReport()); 477 } 478 return countComparisionFailures; 479 } 480 481 /** 482 * Does comparision, error printing and returns failure count for encumbrances 483 * @return failure count 484 */ 485 protected Integer encumbranceCompareHistory() { 486 Integer countComparisionFailures = 0; 487 488 List data = ledgerEntryBalanceCachingDao.encumbranceCompareHistory(Encumbrance.class, EncumbranceHistory.class, getPastFiscalYearsToConsider()); 489 490 if (!data.isEmpty()) { 491 for (Iterator itr = data.iterator(); itr.hasNext();) { 492 EncumbranceHistory encumbranceHistory = createEncumbranceHistoryFromMap((Map)itr.next()); 493 countComparisionFailures++; 494 if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { 495 reportWriterService.writeError(encumbranceHistory, new Message(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, encumbranceHistory.getClass().getSimpleName())); 496 } 497 } 498 499 } else { 500 reportWriterService.writeNewLines(1); 501 reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), (EncumbranceHistory.class).getSimpleName(), countComparisionFailures, this.getComparisonFailuresToPrintPerReport()); 502 } 503 504 505 countComparisionFailures = data.size(); 506 507 return countComparisionFailures; 508 } 509 510 /** 511 * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customPrintRowCountHistory() 512 */ 513 @Override 514 protected void customPrintRowCountHistory(Integer fiscalYear){ 515 // Note that fiscal year is passed as null for the History tables because for those we shouldn't have data prior to the fiscal year anyway (and 516 // if we do it's a bug that should be discovered) 517 reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_ROW_COUNT_HISTORY), this.getShortTableLabel((AccountBalanceHistory.class).getSimpleName()), "(" + (AccountBalanceHistory.class).getSimpleName() + ")", this.getHistoryCount(null, AccountBalanceHistory.class)); 518 reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_ROW_COUNT_PRODUCTION), this.getShortTableLabel((AccountBalance.class).getSimpleName()), accountBalanceDao.findCountGreaterOrEqualThan(fiscalYear)); 519 reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_ROW_COUNT_HISTORY), this.getShortTableLabel((EncumbranceHistory.class).getSimpleName()), "(" + (EncumbranceHistory.class).getSimpleName() + ")", this.getHistoryCount(null, EncumbranceHistory.class)); 520 reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_ROW_COUNT_PRODUCTION), this.getShortTableLabel((Encumbrance.class).getSimpleName()), encumbranceDao.findCountGreaterOrEqualThan(fiscalYear)); 521 } 522 523 /** 524 * Sets the BalancingDao 525 * 526 * @param balancingDao The BalancingDao to set. 527 */ 528 public void setBalancingDao(BalancingDao balancingDao) { 529 this.balancingDao = balancingDao; 530 } 531 532 /** 533 * Sets the AccountBalanceDao 534 * 535 * @param accountBalanceDao The AccountBalanceDao to set. 536 */ 537 public void setAccountBalanceDao(AccountBalanceDao accountBalanceDao) { 538 this.accountBalanceDao = accountBalanceDao; 539 } 540 541 /** 542 * Sets the EncumbranceDao 543 * 544 * @param encumbranceDao The EncumbranceDao to set. 545 */ 546 public void setEncumbranceDao(EncumbranceDao encumbranceDao) { 547 this.encumbranceDao = encumbranceDao; 548 } 549 550 protected BalanceHistory createBalanceFromMap(Map<String, Object> map) { 551 BalanceHistory balance = new BalanceHistory(); 552 balance.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); 553 balance.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); 554 balance.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); 555 balance.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); 556 balance.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); 557 balance.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); 558 balance.setBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); 559 balance.setObjectTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_CODE)); 560 561 balance.setAccountLineAnnualBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ACTUALS_BALANCE_AMOUNT))); 562 balance.setContractsGrantsBeginningBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.CONTRACT_AND_GRANTS_BEGINNING_BALANCE))); 563 balance.setBeginningBalanceLineAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.BEGINNING_BALANCE))); 564 balance.setMonth1Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_1_ACCT_AMT))); 565 balance.setMonth2Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_2_ACCT_AMT))); 566 balance.setMonth3Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_3_ACCT_AMT))); 567 balance.setMonth4Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_4_ACCT_AMT))); 568 balance.setMonth5Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_5_ACCT_AMT))); 569 balance.setMonth6Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_6_ACCT_AMT))); 570 balance.setMonth7Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_7_ACCT_AMT))); 571 balance.setMonth8Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_8_ACCT_AMT))); 572 balance.setMonth9Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_9_ACCT_AMT))); 573 balance.setMonth10Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_10_ACCT_AMT))); 574 balance.setMonth11Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_11_ACCT_AMT))); 575 balance.setMonth12Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_12_ACCT_AMT))); 576 balance.setMonth13Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_13_ACCT_AMT))); 577 578 return balance; 579 580 } 581 582 protected EntryHistory createEntryHistoryFromMap(Map<String, Object> map) { 583 EntryHistory entry = new EntryHistory(); 584 entry.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); 585 entry.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); 586 entry.setFinancialObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); 587 entry.setFinancialBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); 588 entry.setUniversityFiscalPeriodCode((String)map.get(GeneralLedgerConstants.ColumnNames.FISCAL_PERIOD_CODE)); 589 // entry.setFinancialObjectTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_CODE)); 590 entry.setTransactionDebitCreditCode((String)map.get(GeneralLedgerConstants.ColumnNames.TRANSACTION_DEBIT_CREDIT_CD)); 591 entry.setTransactionLedgerEntryAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT))); 592 593 return entry; 594 595 } 596 597 protected AccountBalanceHistory createAccountBalanceHistoryFromMap(Map<String, Object> map) { 598 //UNIV_FISCAL_YR, FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD, CURR_BDLN_BAL_AMT, ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT 599 AccountBalanceHistory accountBalanceHistory = new AccountBalanceHistory(); 600 accountBalanceHistory.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); 601 accountBalanceHistory.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); 602 accountBalanceHistory.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); 603 accountBalanceHistory.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); 604 accountBalanceHistory.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); 605 accountBalanceHistory.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); 606 accountBalanceHistory.setCurrentBudgetLineBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.CURRENT_BUDGET_LINE_BALANCE_AMOUNT))); 607 accountBalanceHistory.setAccountLineActualsBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ACTUALS_BALANCE_AMOUNT))); 608 accountBalanceHistory.setAccountLineEncumbranceBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_BALANCE_AMOUNT))); 609 610 611 return accountBalanceHistory; 612 } 613 614 protected EncumbranceHistory createEncumbranceHistoryFromMap(Map<String, Object> map) { 615 EncumbranceHistory encumbranceHistory = new EncumbranceHistory(); 616 encumbranceHistory.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); 617 encumbranceHistory.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); 618 encumbranceHistory.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); 619 encumbranceHistory.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); 620 encumbranceHistory.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); 621 encumbranceHistory.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); 622 encumbranceHistory.setBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); 623 encumbranceHistory.setDocumentTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.FINANCIAL_DOCUMENT_TYPE_CODE)); 624 encumbranceHistory.setOriginCode((String)map.get(GeneralLedgerConstants.ColumnNames.ORIGINATION_CODE)); 625 encumbranceHistory.setDocumentNumber((String)map.get(GeneralLedgerConstants.ColumnNames.DOCUMENT_NUMBER)); 626 encumbranceHistory.setAccountLineEncumbranceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT))); 627 encumbranceHistory.setAccountLineEncumbranceClosedAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT))); 628 629 630 return encumbranceHistory; 631 } 632 633 protected KualiDecimal convertBigDecimalToKualiDecimal(BigDecimal biggy) { 634 if (ObjectUtils.isNull(biggy)) 635 return new KualiDecimal(0); 636 else 637 return new KualiDecimal(biggy); 638 639 } 640 641 }