use of org.kuali.kfs.sys.Message in project cu-kfs by CU-CommunityApps.
the class CuFileEnterpriseFeederHelperServiceImpl method feedOnFile.
@Override
public void feedOnFile(File doneFile, File dataFile, File reconFile, PrintStream enterpriseFeedPs, String feederProcessName, String reconciliationTableId, EnterpriseFeederStatusAndErrorMessagesWrapper statusAndErrors, LedgerSummaryReport ledgerSummaryReport, ReportWriterService errorStatisticsReport, EnterpriseFeederReportData feederReportData) {
LOG.info("Processing done file: " + doneFile.getAbsolutePath());
List<Message> errorMessages = statusAndErrors.getErrorMessages();
BufferedReader dataFileReader = null;
ReconciliationBlock reconciliationBlock = null;
Reader reconReader = null;
try {
reconReader = new FileReader(reconFile);
reconciliationBlock = reconciliationParserService.parseReconciliationBlock(reconReader, reconciliationTableId);
} catch (IOException e) {
LOG.error("IO Error occured trying to read the recon file.", e);
errorMessages.add(new Message("IO Error occured trying to read the recon file.", Message.TYPE_FATAL));
reconciliationBlock = null;
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
throw new RuntimeException(e);
} catch (RuntimeException e) {
LOG.error("Error occured trying to parse the recon file.", e);
errorMessages.add(new Message("Error occured trying to parse the recon file.", Message.TYPE_FATAL));
reconciliationBlock = null;
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
throw e;
} finally {
if (reconReader != null) {
try {
reconReader.close();
} catch (IOException e) {
LOG.error("Error occured trying to close recon file: " + reconFile.getAbsolutePath(), e);
}
}
}
try {
if (reconciliationBlock == null) {
errorMessages.add(new Message("Unable to parse reconciliation file.", Message.TYPE_FATAL));
} else {
dataFileReader = new BufferedReader(new FileReader(dataFile));
Iterator<LaborOriginEntry> fileIterator = new LaborOriginEntryFileIterator(dataFileReader, false);
reconciliationService.reconcile(fileIterator, reconciliationBlock, errorMessages);
fileIterator = null;
dataFileReader.close();
dataFileReader = null;
}
if (reconciliationProcessSucceeded(errorMessages)) {
dataFileReader = new BufferedReader(new FileReader(dataFile));
String line;
int count = 0;
String offsetDocTypes = null;
if (StringUtils.isNotEmpty(parameterService.getParameterValueAsString(LaborEnterpriseFeedStep.class, LdConstants.LABOR_BENEFIT_OFFSET_DOCTYPE))) {
offsetDocTypes = "," + parameterService.getParameterValueAsString(LaborEnterpriseFeedStep.class, LdConstants.LABOR_BENEFIT_OFFSET_DOCTYPE).replace(";", ",").replace("|", ",") + ",";
}
while ((line = dataFileReader.readLine()) != null) {
try {
LaborOriginEntry tempEntry = new LaborOriginEntry();
tempEntry.setFromTextFileForBatch(line, count);
feederReportData.incrementNumberOfRecordsRead();
feederReportData.addToTotalAmountRead(tempEntry.getTransactionLedgerEntryAmount());
enterpriseFeedPs.printf("%s\n", line);
ledgerSummaryReport.summarizeEntry(tempEntry);
feederReportData.incrementNumberOfRecordsWritten();
feederReportData.addToTotalAmountWritten(tempEntry.getTransactionLedgerEntryAmount());
List<LaborOriginEntry> benefitEntries = generateBenefits(tempEntry, errorStatisticsReport, feederReportData);
KualiDecimal benefitTotal = new KualiDecimal(0);
KualiDecimal offsetTotal = new KualiDecimal(0);
for (LaborOriginEntry benefitEntry : benefitEntries) {
benefitEntry.setTransactionLedgerEntryDescription("FRINGE EXPENSE");
enterpriseFeedPs.printf("%s\n", benefitEntry.getLine());
feederReportData.incrementNumberOfRecordsWritten();
feederReportData.addToTotalAmountWritten(benefitEntry.getTransactionLedgerEntryAmount());
if (benefitEntry.getTransactionLedgerEntryAmount().isZero())
continue;
benefitTotal = benefitTotal.add(benefitEntry.getTransactionLedgerEntryAmount());
}
if (tempEntry.getFinancialBalanceTypeCode() == null || tempEntry.getFinancialBalanceTypeCode().equalsIgnoreCase("IE"))
continue;
List<LaborOriginEntry> offsetEntries = generateOffsets(tempEntry, offsetDocTypes);
for (LaborOriginEntry offsetEntry : offsetEntries) {
if (offsetEntry.getTransactionLedgerEntryAmount().isZero())
continue;
enterpriseFeedPs.printf("%s\n", offsetEntry.getLine());
offsetTotal = offsetTotal.add(offsetEntry.getTransactionLedgerEntryAmount());
}
if (!benefitTotal.equals(offsetTotal)) {
LOG.info("** count:offsetTotal: benefitTotal=" + count + ":" + offsetTotal + "" + benefitTotal);
}
} catch (NullPointerException npe) {
LOG.error("NPE encountered");
throw new RuntimeException(npe.toString());
} catch (Exception e) {
throw new IOException(e.toString());
}
count++;
LOG.info("Processed Entry # " + count);
}
dataFileReader.close();
dataFileReader = null;
// LOG.info("TotalBenifits : " + totalBenefitValue);
statusAndErrors.setStatus(new FileReconOkLoadOkStatus());
} else {
statusAndErrors.setStatus(new FileReconBadLoadAbortedStatus());
}
} catch (Exception e) {
LOG.error("Caught exception when reconciling/loading done file: " + doneFile, e);
statusAndErrors.setStatus(new ExceptionCaughtStatus());
errorMessages.add(new Message("Caught exception attempting to reconcile/load done file: " + doneFile + ". File contents are NOT loaded", Message.TYPE_FATAL));
// re-throw the exception rather than returning a value so that Spring will auto-rollback
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
// Spring only rolls back when throwing a runtime exception (by default), so we throw a new exception
throw new RuntimeException(e);
}
} finally {
if (dataFileReader != null) {
try {
dataFileReader.close();
} catch (IOException e) {
LOG.error("IO Exception occured trying to close connection to the data file", e);
errorMessages.add(new Message("IO Exception occured trying to close connection to the data file", Message.TYPE_FATAL));
}
}
}
}
use of org.kuali.kfs.sys.Message in project cu-kfs by CU-CommunityApps.
the class CuFileEnterpriseFeederServiceImpl method feed.
@Override
public void feed(String processName, boolean performNotifications) {
// to consider: maybe use java NIO classes to perform done file locking?
synchronized (this) {
if (StringUtils.isBlank(directoryName)) {
throw new IllegalArgumentException("directoryName not set for FileEnterpriseFeederServiceImpl.");
}
FileFilter doneFileFilter = new SuffixFileFilter(DONE_FILE_SUFFIX);
File enterpriseFeedFile = null;
String enterpriseFeedFileName = LaborConstants.BatchFileSystem.LABOR_ENTERPRISE_FEED + LaborConstants.BatchFileSystem.EXTENSION;
enterpriseFeedFile = new File(laborOriginEntryDirectoryName + File.separator + enterpriseFeedFileName);
PrintStream enterpriseFeedPs = null;
try {
enterpriseFeedPs = new PrintStream(enterpriseFeedFile);
} catch (FileNotFoundException e) {
LOG.error("enterpriseFeedFile doesn't exist " + enterpriseFeedFileName);
throw new RuntimeException("enterpriseFeedFile doesn't exist " + enterpriseFeedFileName);
}
if (LOG.isInfoEnabled()) {
LOG.info("New File created for enterprise feeder service run: " + enterpriseFeedFileName);
}
File directory = new File(directoryName);
if (!directory.exists() || !directory.isDirectory()) {
LOG.error("Directory doesn't exist and or it's not really a directory " + directoryName);
throw new RuntimeException("Directory doesn't exist and or it's not really a directory " + directoryName);
}
File[] doneFiles = directory.listFiles(doneFileFilter);
reorderDoneFiles(doneFiles);
boolean fatal = false;
LedgerSummaryReport ledgerSummaryReport = new LedgerSummaryReport();
// keeps track of statistics for reporting
EnterpriseFeederReportData feederReportData = new EnterpriseFeederReportData();
List<EnterpriseFeederStatusAndErrorMessagesWrapper> statusAndErrorsList = new ArrayList<EnterpriseFeederStatusAndErrorMessagesWrapper>();
for (File doneFile : doneFiles) {
File dataFile = null;
File reconFile = null;
EnterpriseFeederStatusAndErrorMessagesWrapper statusAndErrors = new EnterpriseFeederStatusAndErrorMessagesWrapper();
statusAndErrors.setErrorMessages(new ArrayList<Message>());
dataFile = getDataFile(doneFile);
reconFile = getReconFile(doneFile);
statusAndErrors.setFileNames(dataFile, reconFile, doneFile);
if (dataFile == null) {
LOG.error("Unable to find data file for done file: " + doneFile.getAbsolutePath());
statusAndErrors.getErrorMessages().add(new Message("Unable to find data file for done file: " + doneFile.getAbsolutePath(), Message.TYPE_FATAL));
statusAndErrors.setStatus(new RequiredFilesMissingStatus());
}
if (reconFile == null) {
LOG.error("Unable to find recon file for done file: " + doneFile.getAbsolutePath());
statusAndErrors.getErrorMessages().add(new Message("Unable to find recon file for done file: " + doneFile.getAbsolutePath(), Message.TYPE_FATAL));
statusAndErrors.setStatus(new RequiredFilesMissingStatus());
}
try {
if (dataFile != null && reconFile != null) {
if (LOG.isInfoEnabled()) {
LOG.info("Data file: " + dataFile.getAbsolutePath());
LOG.info("Reconciliation File: " + reconFile.getAbsolutePath());
}
fileEnterpriseFeederHelperService.feedOnFile(doneFile, dataFile, reconFile, enterpriseFeedPs, processName, reconciliationTableId, statusAndErrors, ledgerSummaryReport, errorStatisticsReport, feederReportData);
}
} catch (RuntimeException e) {
// we need to be extremely resistant to a file load failing so that it doesn't prevent other files from loading
LOG.error("Caught exception when feeding done file: " + doneFile.getAbsolutePath());
fatal = true;
} finally {
statusAndErrorsList.add(statusAndErrors);
boolean doneFileDeleted = doneFile.delete();
if (!doneFileDeleted) {
statusAndErrors.getErrorMessages().add(new Message("Unable to delete done file: " + doneFile.getAbsolutePath(), Message.TYPE_FATAL));
}
if (performNotifications) {
enterpriseFeederNotificationService.notifyFileFeedStatus(processName, statusAndErrors.getStatus(), doneFile, dataFile, reconFile, statusAndErrors.getErrorMessages());
}
}
}
enterpriseFeedPs.close();
// if errors encountered is greater than max allowed the enterprise feed file should not be sent
boolean enterpriseFeedFileCreated = false;
if (feederReportData.getNumberOfErrorEncountered() > getMaximumNumberOfErrorsAllowed() || fatal) {
enterpriseFeedFile.delete();
} else {
// generate done file
String enterpriseFeedDoneFileName = enterpriseFeedFileName.replace(LaborConstants.BatchFileSystem.EXTENSION, LaborConstants.BatchFileSystem.DONE_FILE_EXTENSION);
File enterpriseFeedDoneFile = new File(laborOriginEntryDirectoryName + File.separator + enterpriseFeedDoneFileName);
if (!enterpriseFeedDoneFile.exists()) {
try {
enterpriseFeedDoneFile.createNewFile();
} catch (IOException e) {
LOG.error("Unable to create done file for enterprise feed output group.", e);
throw new RuntimeException("Unable to create done file for enterprise feed output group.", e);
}
}
enterpriseFeedFileCreated = true;
}
// write out totals to log file
if (LOG.isInfoEnabled()) {
LOG.info("Total records read: " + feederReportData.getNumberOfRecordsRead());
LOG.info("Total amount read: " + feederReportData.getTotalAmountRead());
LOG.info("Total records written: " + feederReportData.getNumberOfRecordsRead());
LOG.info("Total amount written: " + feederReportData.getTotalAmountWritten());
}
generateReport(enterpriseFeedFileCreated, feederReportData, statusAndErrorsList, ledgerSummaryReport, laborOriginEntryDirectoryName + File.separator + enterpriseFeedFileName);
}
}
use of org.kuali.kfs.sys.Message in project cu-kfs by CU-CommunityApps.
the class CuScrubberValidatorImpl method checkAccountFringeIndicator.
/**
* Overridden to clear out the sub-account number on fringe transactions
* if the transaction had its account number modified.
*
* @see org.kuali.kfs.module.ld.batch.service.impl.ScrubberValidatorImpl#checkAccountFringeIndicator(
* org.kuali.kfs.module.ld.businessobject.LaborOriginEntry, org.kuali.kfs.module.ld.businessobject.LaborOriginEntry,
* org.kuali.kfs.coa.businessobject.Account, org.kuali.kfs.sys.businessobject.UniversityDate,
* org.kuali.kfs.module.ld.batch.service.LaborAccountingCycleCachingService)
*/
@Override
protected Message checkAccountFringeIndicator(LaborOriginEntry laborOriginEntry, LaborOriginEntry laborWorkingEntry, Account account, UniversityDate universityRunDate, LaborAccountingCycleCachingService laborAccountingCycleCachingService) {
LaborObject laborObject = laborAccountingCycleCachingService.getLaborObject(laborOriginEntry.getUniversityFiscalYear(), laborOriginEntry.getChartOfAccountsCode(), laborOriginEntry.getFinancialObjectCode());
boolean isFringeTransaction = laborObject != null && org.apache.commons.lang.StringUtils.equals(LaborConstants.BenefitExpenseTransfer.LABOR_LEDGER_BENEFIT_CODE, laborObject.getFinancialObjectFringeOrSalaryCode());
if (isFringeTransaction && !account.isAccountsFringesBnftIndicator()) {
Account altAccount = accountService.getByPrimaryId(laborOriginEntry.getAccount().getReportsToChartOfAccountsCode(), laborOriginEntry.getAccount().getReportsToAccountNumber());
if (ObjectUtils.isNotNull(altAccount)) {
laborWorkingEntry.setAccount(altAccount);
laborWorkingEntry.setAccountNumber(altAccount.getAccountNumber());
laborWorkingEntry.setChartOfAccountsCode(altAccount.getChartOfAccountsCode());
Message err = handleExpiredClosedAccount(altAccount, laborOriginEntry, laborWorkingEntry, universityRunDate);
if (err == null) {
err = MessageBuilder.buildMessageWithPlaceHolder(LaborKeyConstants.MESSAGE_FRINGES_MOVED_TO, Message.TYPE_WARNING, new Object[] { altAccount.getAccountNumber() });
}
clearSubAccountOnModifiedFringeTransaction(laborOriginEntry, laborWorkingEntry, laborAccountingCycleCachingService, err);
return err;
}
boolean suspenseAccountLogicInd = parameterService.getParameterValueAsBoolean(LaborScrubberStep.class, LaborConstants.Scrubber.SUSPENSE_ACCOUNT_LOGIC_PARAMETER);
if (suspenseAccountLogicInd) {
return useSuspenseAccount(laborWorkingEntry);
}
return MessageBuilder.buildMessage(LaborKeyConstants.ERROR_NON_FRINGE_ACCOUNT_ALTERNATIVE_NOT_FOUND, Message.TYPE_FATAL);
}
return handleExpiredClosedAccount(account, laborOriginEntry, laborWorkingEntry, universityRunDate);
}
use of org.kuali.kfs.sys.Message in project cu-kfs by CU-CommunityApps.
the class ScrubberValidatorImpl method validateBalanceType.
/**
* Validates the balance type of the origin entry
*
* @param originEntry the origin entry being scrubbed
* @param workingEntry the scrubbed version of the origin entry
* @return a Message if an error was encountered, otherwise null
*/
protected Message validateBalanceType(OriginEntryInformation originEntry, OriginEntryInformation workingEntry, AccountingCycleCachingService accountingCycleCachingService) {
LOG.debug("validateBalanceType() started");
// balance type IS NOT empty
String balanceTypeCode = originEntry.getFinancialBalanceTypeCode();
if (StringUtils.hasText(balanceTypeCode)) {
BalanceType originEntryBalanceType = accountingCycleCachingService.getBalanceType(originEntry.getFinancialBalanceTypeCode());
if (originEntryBalanceType == null) {
// balance type IS NOT valid
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_BALANCE_TYPE_NOT_FOUND, " (" + balanceTypeCode + ")", Message.TYPE_FATAL);
} else if (!originEntryBalanceType.isActive()) {
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_BALANCE_TYPE_NOT_ACTIVE, balanceTypeCode, Message.TYPE_FATAL);
} else {
// balance type IS valid
if (originEntryBalanceType.isFinancialOffsetGenerationIndicator()) {
// entry IS an offset
if (originEntry.getTransactionLedgerEntryAmount().isNegative()) {
// it's an INVALID non-budget transaction
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_TRANS_CANNOT_BE_NEGATIVE_IF_OFFSET, Message.TYPE_FATAL);
} else {
// it's a VALID non-budget transaction
if (!originEntry.isCredit() && !originEntry.isDebit()) {
// debit or a credit
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_DC_INDICATOR_MUST_BE_D_OR_C, originEntry.getTransactionDebitCreditCode(), Message.TYPE_FATAL);
} else {
workingEntry.setFinancialBalanceTypeCode(balanceTypeCode);
}
}
} else {
// entry IS NOT an offset, means it's a budget transaction
if (StringUtils.hasText(originEntry.getTransactionDebitCreditCode())) {
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_DC_INDICATOR_MUST_BE_EMPTY, originEntry.getTransactionDebitCreditCode(), Message.TYPE_FATAL);
} else {
if (originEntry.isCredit() || originEntry.isDebit()) {
// budget transactions must be neither debit nor credit
return MessageBuilder.buildMessage(KFSKeyConstants.ERROR_DC_INDICATOR_MUST_BE_NEITHER_D_NOR_C, originEntry.getTransactionDebitCreditCode(), Message.TYPE_FATAL);
} else {
// it's a valid budget transaction
workingEntry.setFinancialBalanceTypeCode(balanceTypeCode);
}
}
}
}
} else {
// balance type IS empty. We can't set it if the year isn't set
SystemOptions workingEntryOption = accountingCycleCachingService.getSystemOptions(workingEntry.getUniversityFiscalYear());
if (workingEntryOption != null) {
workingEntry.setFinancialBalanceTypeCode(workingEntryOption.getActualFinancialBalanceTypeCd());
} else {
// TODO:- need to change to use MessageBuilder
return new Message("Unable to set balance type code when year is unknown: " + workingEntry.getUniversityFiscalYear(), Message.TYPE_FATAL);
}
}
return null;
}
use of org.kuali.kfs.sys.Message in project cu-kfs by CU-CommunityApps.
the class CuPosterServiceImpl method getAccountWithPotentialContinuation.
/**
* Overridden so that the errors list will not be updated when a continuation account gets used,
* thus allowing the ICR continuation to be processed properly by the Poster.
*
* @see org.kuali.kfs.gl.batch.service.impl.PosterServiceImpl#getAccountWithPotentialContinuation(
* org.kuali.kfs.gl.businessobject.Transaction, java.util.List)
*/
@Override
protected Account getAccountWithPotentialContinuation(Transaction tran, List<Message> errors) {
Account account = accountingCycleCachingService.getAccount(tran.getChartOfAccountsCode(), tran.getAccountNumber());
if (ObjectUtils.isNotNull(account) && account.isClosed()) {
Account contAccount = account;
for (int i = 0; i < CONTINUATION_ACCOUNT_DEPTH_LIMIT && ObjectUtils.isNotNull(contAccount) && contAccount.isClosed(); i++) {
contAccount = accountingCycleCachingService.getAccount(contAccount.getContinuationFinChrtOfAcctCd(), contAccount.getContinuationAccountNumber());
}
if (ObjectUtils.isNull(contAccount) || contAccount == account || contAccount.isClosed()) {
errors.add(new Message(MessageFormat.format(configurationService.getPropertyValueAsString(KFSKeyConstants.ERROR_ICRACCOUNT_CONTINUATION_ACCOUNT_CLOSED), tran.getChartOfAccountsCode(), tran.getAccountNumber(), CONTINUATION_ACCOUNT_DEPTH_LIMIT), Message.TYPE_WARNING));
} else {
final String formattedErrorMessage = MessageFormat.format(configurationService.getPropertyValueAsString(KFSKeyConstants.WARNING_ICRACCOUNT_CONTINUATION_ACCOUNT_USED), tran.getChartOfAccountsCode(), tran.getAccountNumber(), contAccount.getChartOfAccountsCode(), contAccount.getAccountNumber());
LOG.warn(formattedErrorMessage);
account = contAccount;
((OriginEntryInformation) tran).setChartOfAccountsCode(contAccount.getChartOfAccountsCode());
((OriginEntryInformation) tran).setAccountNumber(contAccount.getAccountNumber());
}
}
return account;
}
Aggregations