/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.gl.batch.service.impl; import java.io.File; import java.io.FilenameFilter; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.gl.GeneralLedgerConstants; import org.kuali.kfs.gl.batch.PosterBalancingStep; import org.kuali.kfs.gl.batch.service.BalancingService; import org.kuali.kfs.gl.businessobject.AccountBalance; import org.kuali.kfs.gl.businessobject.AccountBalanceHistory; import org.kuali.kfs.gl.businessobject.Balance; import org.kuali.kfs.gl.businessobject.BalanceHistory; import org.kuali.kfs.gl.businessobject.Encumbrance; import org.kuali.kfs.gl.businessobject.EncumbranceHistory; import org.kuali.kfs.gl.businessobject.Entry; import org.kuali.kfs.gl.businessobject.EntryHistory; import org.kuali.kfs.gl.businessobject.LedgerBalanceHistory; import org.kuali.kfs.gl.businessobject.OriginEntryFull; import org.kuali.kfs.gl.businessobject.OriginEntryInformation; import org.kuali.kfs.gl.dataaccess.AccountBalanceDao; import org.kuali.kfs.gl.dataaccess.BalancingDao; import org.kuali.kfs.gl.dataaccess.EncumbranceDao; import org.kuali.kfs.sys.FileUtil; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.Message; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.krad.util.ObjectUtils; import org.springframework.transaction.annotation.Transactional; /** * Service implementation of BalancingService of GL balancing */ @Transactional public class BalancingServiceImpl extends BalancingServiceBaseImpl<EntryHistory, BalanceHistory> implements BalancingService { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalancingServiceImpl.class); protected BalancingDao balancingDao; protected AccountBalanceDao accountBalanceDao; protected EncumbranceDao encumbranceDao; protected File posterInputFile = null; protected File posterErrorOutputFile = null; protected File reversalInputFile = null; protected File reversalErrorOutputFile = null; protected File icrInputFile = null; protected File icrErrorOutputFile = null; protected File icrEncumbranceInputFile = null; protected File icrEncumbranceErrorOutputFile = null; @Override public boolean runBalancing() { // clear out the file cache, otherwise, it won't update the history tables with the latest poster files // 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 clearPosterFileCache(); return super.runBalancing(); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getPosterInputFile() */ @Override public File getPosterInputFile() { // avoid running scanning logic on file system if (posterInputFile != null) { return posterInputFile; } return posterInputFile = getFile( GeneralLedgerConstants.BatchFileSystem.POSTER_INPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getPosterErrorOutputFile() */ @Override public File getPosterErrorOutputFile() { // avoid running scanning logic on file system if (posterErrorOutputFile != null) { return posterErrorOutputFile; } return posterErrorOutputFile = getFile( GeneralLedgerConstants.BatchFileSystem.POSTER_ERROR_OUTPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getReversalInputFile() */ @Override public File getReversalInputFile(){ if (reversalInputFile != null) { return reversalInputFile; } return reversalInputFile = getFile( GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_VALID_OUTPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getReversalErrorOutputFile() */ @Override public File getReversalErrorOutputFile(){ if (reversalErrorOutputFile != null) { return reversalErrorOutputFile; } return reversalErrorOutputFile = getFile( GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_ERROR_OUTPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getICRInputFile() */ @Override public File getICRInputFile(){ if (icrInputFile != null) { return icrInputFile; } return icrInputFile = getFile( GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_INPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getICRErrorOutputFile() */ @Override public File getICRErrorOutputFile(){ if (icrErrorOutputFile != null) { return icrErrorOutputFile; } return icrErrorOutputFile = getFile( GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_ERROR_OUTPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getICREncumbranceInputFile() */ @Override public File getICREncumbranceInputFile(){ if (icrEncumbranceInputFile != null) { return icrEncumbranceInputFile; } return icrEncumbranceInputFile = getFile( GeneralLedgerConstants.BatchFileSystem.ICR_ENCUMBRANCE_POSTER_INPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getICREncumbranceErrorOutputFile() */ @Override public File getICREncumbranceErrorOutputFile(){ if (icrEncumbranceErrorOutputFile != null) { return icrEncumbranceErrorOutputFile; } return icrEncumbranceErrorOutputFile = getFile( GeneralLedgerConstants.BatchFileSystem.ICR_ENCUMBRANCE_POSTER_ERROR_OUTPUT_FILE, GeneralLedgerConstants.BatchFileSystem.EXTENSION); } public File getFile(final String fileName, final String fileExtension){ FilenameFilter filenameFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return (name.startsWith(fileName) && name.endsWith(fileExtension)); } }; return FileUtil.getNewestFile(new File(batchFileDirectoryName), filenameFilter); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getPastFiscalYearsToConsider() */ @Override public int getPastFiscalYearsToConsider() { return Integer.parseInt(parameterService.getParameterValueAsString(PosterBalancingStep.class, GeneralLedgerConstants.Balancing.NUMBER_OF_PAST_FISCAL_YEARS_TO_INCLUDE)); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getComparisonFailuresToPrintPerReport() */ @Override public int getComparisonFailuresToPrintPerReport() { return Integer.parseInt(parameterService.getParameterValueAsString(PosterBalancingStep.class, GeneralLedgerConstants.Balancing.NUMBER_OF_COMPARISON_FAILURES_TO_PRINT_PER_REPORT)); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getShortTableLabel(java.lang.String) */ @Override public String getShortTableLabel(String businessObjectName) { Map<String, String> names = new HashMap<String, String>(); names.put((Entry.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENTRY_LABEL)); names.put((EntryHistory.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENTRY_LABEL)); names.put((Balance.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_BALANCE_LABEL)); names.put((BalanceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_BALANCE_LABEL)); names.put((AccountBalance.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_LABEL)); names.put((AccountBalanceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_LABEL)); names.put((Encumbrance.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_LABEL)); names.put((EncumbranceHistory.class).getSimpleName(), kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_LABEL)); return names.get(businessObjectName) == null ? kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_UNKNOWN_LABEL) : names.get(businessObjectName); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getOriginEntry(java.lang.String, int) */ @Override public OriginEntryInformation getOriginEntry(String inputLine, int lineNumber) { // We need a OriginEntryFull because that's what updateBalanceHistory is looking for OriginEntryFull originEntry = new OriginEntryFull(); originEntry.setFromTextFileForBatch(inputLine, lineNumber); return originEntry; } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#updateEntryHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) * @see org.kuali.kfs.gl.batch.service.impl.PostEntry#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) */ @Override public void updateEntryHistory(Integer postMode, OriginEntryInformation originEntry) { // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? EntryHistory entryHistory = new EntryHistory(originEntry); EntryHistory retrievedEntryHistory = (EntryHistory) businessObjectService.retrieve(entryHistory); if(ObjectUtils.isNotNull(retrievedEntryHistory)) { entryHistory = retrievedEntryHistory; } entryHistory.addAmount(originEntry.getTransactionLedgerEntryAmount()); businessObjectService.save(entryHistory); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#updateBalanceHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) * @see org.kuali.kfs.gl.batch.service.impl.PostBalance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) */ @Override public void updateBalanceHistory(Integer postMode, OriginEntryInformation originEntry) { // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; BalanceHistory balanceHistory = new BalanceHistory(originEntryFull); BalanceHistory retrievedBalanceHistory = (BalanceHistory) businessObjectService.retrieve(balanceHistory); if(ObjectUtils.isNotNull(retrievedBalanceHistory)) { balanceHistory = retrievedBalanceHistory; } KualiDecimal amount = originEntryFull.getTransactionLedgerEntryAmount(); // Make sure the amount update properly recognized debit / credit logic. This is modeled after PostBalance#post originEntryFull.refreshReferenceObject(KFSPropertyConstants.BALANCE_TYPE); originEntryFull.refreshReferenceObject(KFSPropertyConstants.OBJECT_TYPE); if (originEntryFull.getBalanceType().isFinancialOffsetGenerationIndicator()) { if (!originEntryFull.getTransactionDebitCreditCode().equals(originEntryFull.getObjectType().getFinObjectTypeDebitcreditCd())) { amount = amount.negated(); } } balanceHistory.addAmount(originEntryFull.getUniversityFiscalPeriodCode(), amount); businessObjectService.save(balanceHistory); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getBalance(org.kuali.kfs.gl.businessobject.LedgerBalanceHistory) */ @Override public Balance getBalance(LedgerBalanceHistory ledgerBalanceHistory) { Balance balance = new Balance((BalanceHistory) ledgerBalanceHistory); return (Balance) businessObjectService.retrieve(balance); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#clearPosterFileCache() */ @Override public void clearPosterFileCache() { this.posterInputFile = null; this.posterErrorOutputFile = null; this.reversalInputFile = null; this.reversalErrorOutputFile = null; this.icrInputFile = null; this.icrErrorOutputFile = null; this.icrEncumbranceInputFile = null; this.icrEncumbranceErrorOutputFile = null; } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customPopulateHistoryTables(java.lang.Integer) */ @Override public void customPopulateHistoryTables(Integer fiscalYear) { balancingDao.populateAccountBalancesHistory(fiscalYear); balancingDao.populateEncumbranceHistory(fiscalYear); } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#doesCustomHistoryExist(java.lang.Integer) */ @Override protected boolean doesCustomHistoryExist(Integer fiscalYear) { return (this.getHistoryCount(fiscalYear, AccountBalanceHistory.class) > 0 && this.getHistoryCount(fiscalYear, EncumbranceHistory.class) > 0); } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#deleteCustomHistory(java.lang.Integer) */ @Override protected void deleteCustomHistory(Integer fiscalYear) { deleteHistory(fiscalYear, AccountBalanceHistory.class); deleteHistory(fiscalYear, EncumbranceHistory.class); reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_OBSOLETE_FISCAL_YEAR_DATA_DELETED), (AccountBalanceHistory.class).getSimpleName(), (EncumbranceHistory.class).getSimpleName(), fiscalYear); reportWriterService.writeNewLines(1); } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#updateCustomHistory(org.kuali.kfs.gl.businessobject.OriginEntryInformation) */ @Override protected void updateCustomHistory(Integer postMode, OriginEntryInformation originEntry) { this.updateAccountBalanceHistory(originEntry); this.updateEncumbranceHistory(originEntry); } /** * Update the account balance history table * @param originEntry representing the update details * @see org.kuali.kfs.gl.batch.service.impl.PostAccountBalance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) */ protected void updateAccountBalanceHistory(OriginEntryInformation originEntry) { OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; // As taken from PostAccountBalance#post: only post transactions where: balance type code is AC or CB or where object type // isn't FB and // balance type code is EX, IE, PE and CE originEntryFull.refreshReferenceObject(KFSPropertyConstants.OPTION); 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()))) { // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? AccountBalanceHistory accountBalanceHistory = new AccountBalanceHistory(originEntry); AccountBalanceHistory retrievedAccountBalanceHistory = (AccountBalanceHistory) businessObjectService.retrieve(accountBalanceHistory); if(ObjectUtils.isNotNull(retrievedAccountBalanceHistory)) { accountBalanceHistory = retrievedAccountBalanceHistory; } // Following is a copy of PostAccountBalance.updateAccountBalanceReturn since the blancing process is to do this // independently if (accountBalanceHistory.addAmount(originEntryFull)) { businessObjectService.save(accountBalanceHistory); } } } /** * * @see org.kuali.kfs.gl.batch.service.BalancingService#clearBalanceHistory() */ @Override public void clearHistories() { Map<String, Object> fieldValues = new HashMap<String, Object>(); businessObjectService.deleteMatching(EntryHistory.class, fieldValues); businessObjectService.deleteMatching(BalanceHistory.class, fieldValues); businessObjectService.deleteMatching(EncumbranceHistory.class, fieldValues); businessObjectService.deleteMatching(AccountBalanceHistory.class, fieldValues); reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_HISTORY_PURGED)); } /** * @see org.kuali.kfs.gl.batch.service.BalancingService#getFilenames() */ @Override public String getFilenames() { return (this.posterInputFile == null ? null : this.posterInputFile.getName()) + "\n" + (this.posterErrorOutputFile == null ? null : this.posterErrorOutputFile.getName()) + "\n" + (this.reversalInputFile == null ? null : this.reversalInputFile.getName()) + "\n" + (this.reversalErrorOutputFile == null ? null : this.reversalErrorOutputFile.getName()) + "\n" + (this.icrInputFile == null ? null : this.icrInputFile.getName()) + "\n" + (this.icrErrorOutputFile == null ? null : this.icrErrorOutputFile.getName()) + "\n" + (this.icrEncumbranceInputFile == null ? null : this.icrEncumbranceInputFile.getName()) + "\n" + (this.icrEncumbranceErrorOutputFile == null ? null : this.icrEncumbranceErrorOutputFile.getName()); } /** * Compares entries in the Balance and BalanceHistory tables to ensure the amounts match. * @return count is compare failures */ @Override protected Integer compareBalanceHistory() { Integer countComparisionFailures = 0; String balanceTable = persistenceStructureService.getTableName(Balance.class); String historyTable = persistenceStructureService.getTableName(balanceHistoryPersistentClass); List<Balance> data = ledgerEntryBalanceCachingDao.compareBalanceHistory(balanceTable, historyTable, getFiscalYear()); if (!data.isEmpty()) { for (Iterator<Balance> itr = data.iterator(); itr.hasNext();) { BalanceHistory balance = createBalanceFromMap((Map<String, Object>)itr.next()); countComparisionFailures++; if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { reportWriterService.writeError(balance, new Message(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, balance.getClass().getSimpleName())); } } } return countComparisionFailures; } /** * Compares entries in the Entry and EntryHistory tables to ensure the amounts match. * @return count is compare failures */ @Override protected Integer compareEntryHistory() { Integer countComparisionFailures = 0; String entryTable = persistenceStructureService.getTableName(Entry.class); String historyTable = persistenceStructureService.getTableName(entryHistoryPersistentClass); List<Entry> data = ledgerEntryBalanceCachingDao.compareEntryHistory(entryTable, historyTable, getFiscalYear()); if (!data.isEmpty()) { for (Iterator<Entry> itr = data.iterator(); itr.hasNext();) { EntryHistory entry = createEntryHistoryFromMap((Map<String, Object>)itr.next()); countComparisionFailures++; if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { reportWriterService.writeError(entry, new Message(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, entry.getClass().getSimpleName())); } } } return countComparisionFailures; } /** * Update the encumbrance history table * @param originEntry representing the update details * @see org.kuali.kfs.gl.batch.service.impl.PostEncumbrance#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) */ protected void updateEncumbranceHistory(OriginEntryInformation originEntry) { OriginEntryFull originEntryFull = (OriginEntryFull) originEntry; // PostEncumbrance.verifyTransaction is not run because entries that fail that verification will be in the error poster file // which entries // are already ignored before being passed to this method. // 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 originEntryFull.refreshReferenceObject(KFSPropertyConstants.OPTION); if ((StringUtils.isBlank(originEntryFull.getTransactionEncumbranceUpdateCode())) || " ".equals(originEntryFull.getTransactionEncumbranceUpdateCode()) || KFSConstants.ENCUMB_UPDT_NO_ENCUMBRANCE_CD.equals(originEntryFull.getTransactionEncumbranceUpdateCode()) || originEntryFull.getOption().getFinObjectTypeFundBalanceCd().equals(originEntryFull.getFinancialObjectTypeCode())) { return; } EncumbranceHistory encumbranceHistory = new EncumbranceHistory(originEntryFull); if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(originEntryFull.getTransactionEncumbranceUpdateCode())) { encumbranceHistory.setDocumentNumber(originEntryFull.getReferenceFinancialDocumentNumber()); encumbranceHistory.setOriginCode(originEntryFull.getReferenceFinancialSystemOriginationCode()); encumbranceHistory.setDocumentTypeCode(originEntryFull.getReferenceFinancialDocumentTypeCode()); } // TODO Retrieve and update 1 by 1? Is a HashMap or cache better so that storing only occurs once at the end? EncumbranceHistory retrievedEncumbranceHistory = (EncumbranceHistory) businessObjectService.retrieve(encumbranceHistory); if(ObjectUtils.isNotNull(retrievedEncumbranceHistory)) { encumbranceHistory = retrievedEncumbranceHistory; } // Following is a copy & paste of PostEncumbrance.updateEncumbrance since the balancing process is to do this independently encumbranceHistory.addAmount(originEntryFull); businessObjectService.save(encumbranceHistory); } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customCompareHistory() */ @Override protected Map<String, Integer> customCompareHistory() { Integer countAccountBalanceComparisionFailure = this.accountBalanceCompareHistory(); Integer countEncumbranceComparisionFailure = this.encumbranceCompareHistory(); // Using LinkedHashMap because we want it ordered Map<String, Integer> countMap = new LinkedHashMap<String, Integer>(); countMap.put((AccountBalanceHistory.class).getSimpleName(), countAccountBalanceComparisionFailure); countMap.put((EncumbranceHistory.class).getSimpleName(), countEncumbranceComparisionFailure); return countMap; } /** * Does comparision, error printing and returns failure count for account balances * @return failure count */ protected Integer accountBalanceCompareHistory() { Integer countComparisionFailures = 0; String accountBalanceTable = persistenceStructureService.getTableName(AccountBalance.class); String historyTable = persistenceStructureService.getTableName(AccountBalanceHistory.class); List<AccountBalance> data = ledgerEntryBalanceCachingDao.accountBalanceCompareHistory(accountBalanceTable, historyTable, getFiscalYear()); if (!data.isEmpty()) { for (Iterator<AccountBalance> itr = data.iterator(); itr.hasNext();) { AccountBalanceHistory accountBalanceHistory = createAccountBalanceHistoryFromMap((Map<String, Object>)itr.next()); countComparisionFailures++; if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { reportWriterService.writeError(accountBalanceHistory, new Message(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, accountBalanceHistory.getClass().getSimpleName())); } } } else { reportWriterService.writeNewLines(1); reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), (AccountBalanceHistory.class).getSimpleName(), countComparisionFailures, this.getComparisonFailuresToPrintPerReport()); } return countComparisionFailures; } /** * Does comparision, error printing and returns failure count for encumbrances * @return failure count */ protected Integer encumbranceCompareHistory() { Integer countComparisionFailures = 0; String encumbranceTable = persistenceStructureService.getTableName(Encumbrance.class); String historyTable = persistenceStructureService.getTableName(EncumbranceHistory.class); List<Encumbrance> data = ledgerEntryBalanceCachingDao.encumbranceCompareHistory(encumbranceTable, historyTable, getFiscalYear()); if (!data.isEmpty()) { for (Iterator<Encumbrance> itr = data.iterator(); itr.hasNext();) { EncumbranceHistory encumbranceHistory = createEncumbranceHistoryFromMap((Map<String, Object>)itr.next()); countComparisionFailures++; if (countComparisionFailures <= this.getComparisonFailuresToPrintPerReport()) { reportWriterService.writeError(encumbranceHistory, new Message(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_FAILED_BALANCING), Message.TYPE_WARNING, encumbranceHistory.getClass().getSimpleName())); } } } else { reportWriterService.writeNewLines(1); reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), (EncumbranceHistory.class).getSimpleName(), countComparisionFailures, this.getComparisonFailuresToPrintPerReport()); } countComparisionFailures = data.size(); return countComparisionFailures; } /** * @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl#customPrintRowCountHistory() */ @Override protected void customPrintRowCountHistory(Integer fiscalYear) { // 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 // if we do it's a bug that should be discovered) reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_ROW_COUNT_HISTORY), this.getShortTableLabel((AccountBalanceHistory.class).getSimpleName()), "(" + (AccountBalanceHistory.class).getSimpleName() + ")", this.getHistoryCount(null, AccountBalanceHistory.class)); reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ACCOUNT_BALANCE_ROW_COUNT_PRODUCTION), this.getShortTableLabel((AccountBalance.class).getSimpleName()), accountBalanceDao.findCountGreaterOrEqualThan(fiscalYear)); reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_ROW_COUNT_HISTORY), this.getShortTableLabel((EncumbranceHistory.class).getSimpleName()), "(" + (EncumbranceHistory.class).getSimpleName() + ")", this.getHistoryCount(null, EncumbranceHistory.class)); reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyValueAsString(KFSKeyConstants.Balancing.REPORT_ENCUMBRANCE_ROW_COUNT_PRODUCTION), this.getShortTableLabel((Encumbrance.class).getSimpleName()), encumbranceDao.findCountGreaterOrEqualThan(fiscalYear)); } /** * Sets the BalancingDao * * @param balancingDao The BalancingDao to set. */ public void setBalancingDao(BalancingDao balancingDao) { this.balancingDao = balancingDao; } /** * Sets the AccountBalanceDao * * @param accountBalanceDao The AccountBalanceDao to set. */ public void setAccountBalanceDao(AccountBalanceDao accountBalanceDao) { this.accountBalanceDao = accountBalanceDao; } /** * Sets the EncumbranceDao * * @param encumbranceDao The EncumbranceDao to set. */ public void setEncumbranceDao(EncumbranceDao encumbranceDao) { this.encumbranceDao = encumbranceDao; } protected BalanceHistory createBalanceFromMap(Map<String, Object> map) { BalanceHistory balance = new BalanceHistory(); balance.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); balance.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); balance.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); balance.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); balance.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); balance.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); balance.setBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); balance.setObjectTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_CODE)); balance.setAccountLineAnnualBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ACTUALS_BALANCE_AMOUNT))); balance.setContractsGrantsBeginningBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.CONTRACT_AND_GRANTS_BEGINNING_BALANCE))); balance.setBeginningBalanceLineAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.BEGINNING_BALANCE))); balance.setMonth1Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_1_ACCT_AMT))); balance.setMonth2Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_2_ACCT_AMT))); balance.setMonth3Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_3_ACCT_AMT))); balance.setMonth4Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_4_ACCT_AMT))); balance.setMonth5Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_5_ACCT_AMT))); balance.setMonth6Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_6_ACCT_AMT))); balance.setMonth7Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_7_ACCT_AMT))); balance.setMonth8Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_8_ACCT_AMT))); balance.setMonth9Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_9_ACCT_AMT))); balance.setMonth10Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_10_ACCT_AMT))); balance.setMonth11Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_11_ACCT_AMT))); balance.setMonth12Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_12_ACCT_AMT))); balance.setMonth13Amount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.MONTH_13_ACCT_AMT))); return balance; } protected EntryHistory createEntryHistoryFromMap(Map<String, Object> map) { EntryHistory entry = new EntryHistory(); entry.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); entry.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); entry.setFinancialObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); entry.setFinancialBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); entry.setUniversityFiscalPeriodCode((String)map.get(GeneralLedgerConstants.ColumnNames.FISCAL_PERIOD_CODE)); // entry.setFinancialObjectTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_CODE)); entry.setTransactionDebitCreditCode((String)map.get(GeneralLedgerConstants.ColumnNames.TRANSACTION_DEBIT_CREDIT_CD)); entry.setTransactionLedgerEntryAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT))); return entry; } protected AccountBalanceHistory createAccountBalanceHistoryFromMap(Map<String, Object> map) { // 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 AccountBalanceHistory accountBalanceHistory = new AccountBalanceHistory(); accountBalanceHistory.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); accountBalanceHistory.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); accountBalanceHistory.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); accountBalanceHistory.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); accountBalanceHistory.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); accountBalanceHistory.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); accountBalanceHistory.setCurrentBudgetLineBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.CURRENT_BUDGET_LINE_BALANCE_AMOUNT))); accountBalanceHistory.setAccountLineActualsBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ACTUALS_BALANCE_AMOUNT))); accountBalanceHistory.setAccountLineEncumbranceBalanceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_BALANCE_AMOUNT))); return accountBalanceHistory; } protected EncumbranceHistory createEncumbranceHistoryFromMap(Map<String, Object> map) { EncumbranceHistory encumbranceHistory = new EncumbranceHistory(); encumbranceHistory.setUniversityFiscalYear(((BigDecimal)(map.get(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR))).intValue()); encumbranceHistory.setChartOfAccountsCode((String)map.get(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE)); encumbranceHistory.setAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER)); encumbranceHistory.setSubAccountNumber((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER)); encumbranceHistory.setObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE)); encumbranceHistory.setSubObjectCode((String)map.get(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE)); encumbranceHistory.setBalanceTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE)); encumbranceHistory.setDocumentTypeCode((String)map.get(GeneralLedgerConstants.ColumnNames.FINANCIAL_DOCUMENT_TYPE_CODE)); encumbranceHistory.setOriginCode((String)map.get(GeneralLedgerConstants.ColumnNames.ORIGINATION_CODE)); encumbranceHistory.setDocumentNumber((String)map.get(GeneralLedgerConstants.ColumnNames.DOCUMENT_NUMBER)); encumbranceHistory.setAccountLineEncumbranceAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT))); encumbranceHistory.setAccountLineEncumbranceClosedAmount(convertBigDecimalToKualiDecimal((BigDecimal)map.get(GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT))); return encumbranceHistory; } protected KualiDecimal convertBigDecimalToKualiDecimal(BigDecimal biggy) { if (ObjectUtils.isNull(biggy)) { return new KualiDecimal(0); } else { return new KualiDecimal(biggy); } } }