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 }