/* * 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.module.bc.document.service.impl; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.coa.businessobject.ObjectCode; import org.kuali.kfs.coa.businessobject.SubObjectCode; import org.kuali.kfs.integration.ld.LaborLedgerObject; import org.kuali.kfs.integration.ld.LaborModuleService; import org.kuali.kfs.module.bc.BCConstants; import org.kuali.kfs.module.bc.BCConstants.RequestImportFileType; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionFundingLock; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionHeader; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionLockStatus; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionMonthly; import org.kuali.kfs.module.bc.businessobject.BudgetConstructionRequestMove; import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionGeneralLedger; import org.kuali.kfs.module.bc.document.BudgetConstructionDocument; import org.kuali.kfs.module.bc.document.dataaccess.ImportRequestDao; import org.kuali.kfs.module.bc.document.service.BenefitsCalculationService; import org.kuali.kfs.module.bc.document.service.BudgetDocumentService; import org.kuali.kfs.module.bc.document.service.BudgetParameterService; import org.kuali.kfs.module.bc.document.service.BudgetRequestImportService; import org.kuali.kfs.module.bc.document.service.LockService; import org.kuali.kfs.module.bc.document.validation.impl.BudgetConstructionRuleUtil; import org.kuali.kfs.module.bc.util.BudgetParameterFinder; import org.kuali.kfs.module.bc.util.ImportRequestFileParsingHelper; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSParameterKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.service.NonTransactional; import org.kuali.kfs.sys.service.OptionsService; import org.kuali.kfs.sys.service.impl.KfsParameterConstants; import org.kuali.rice.core.api.util.type.KualiInteger; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer; import org.kuali.rice.kns.service.DictionaryValidationService; import org.kuali.rice.kns.service.DocumentHelperService; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.service.DocumentService; import org.kuali.rice.krad.service.PersistenceService; import org.kuali.rice.krad.util.KRADConstants; import org.kuali.rice.krad.util.ObjectUtils; import org.springframework.transaction.annotation.Transactional; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfWriter; /** * Contains services relevent to the budget construction import request process */ public class BudgetRequestImportServiceImpl implements BudgetRequestImportService { protected BusinessObjectService businessObjectService; protected ImportRequestDao importRequestDao; protected DictionaryValidationService dictionaryValidationService; protected LockService lockService; protected BudgetDocumentService budgetDocumentService; protected LaborModuleService laborModuleService; protected BudgetParameterService budgetParameterService; protected OptionsService optionsService; protected DocumentHelperService documentHelperService; protected DocumentService documentService; protected ParameterService parameterService; protected PersistenceService persistenceServiceOjb; private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(BudgetRequestImportServiceImpl.class); /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#generatePdf(java.util.List, java.io.ByteArrayOutputStream) */ @NonTransactional public void generatePdf(List<String> errorMessages, ByteArrayOutputStream baos) throws DocumentException { Document document = new Document(); PdfWriter.getInstance(document, baos); document.open(); for (String error : errorMessages) { document.add(new Paragraph(error)); } document.close(); } /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#processImportFile(java.io.InputStream, java.lang.String, * java.lang.String, java.lang.String) */ @Transactional public List processImportFile(InputStream fileImportStream, String principalId, String fieldSeperator, String textDelimiter, String fileType, Integer budgetYear) throws IOException { List fileErrorList = new ArrayList(); deleteBudgetConstructionMoveRecords(principalId); BudgetConstructionRequestMove budgetConstructionRequestMove = new BudgetConstructionRequestMove(); BufferedReader fileReader = new BufferedReader(new InputStreamReader(fileImportStream)); int currentLine = 1; while (fileReader.ready()) { String line = StringUtils.strip(fileReader.readLine()); boolean isAnnualFile = (fileType.equalsIgnoreCase(RequestImportFileType.ANNUAL.toString())) ? true : false; if (StringUtils.isNotBlank(line)) { budgetConstructionRequestMove = ImportRequestFileParsingHelper.parseLine(line, fieldSeperator, textDelimiter, isAnnualFile); // check if there were errors parsing the line if (budgetConstructionRequestMove == null) { fileErrorList.add(BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + currentLine + "."); // clean out table since file processing has stopped deleteBudgetConstructionMoveRecords(principalId); return fileErrorList; } String lineValidationError = validateLine(budgetConstructionRequestMove, currentLine, isAnnualFile); if ( StringUtils.isNotEmpty(lineValidationError) ) { fileErrorList.add(lineValidationError); // clean out table since file processing has stopped deleteBudgetConstructionMoveRecords(principalId); return fileErrorList; } // set default values if (StringUtils.isBlank(budgetConstructionRequestMove.getSubAccountNumber())) { budgetConstructionRequestMove.setSubAccountNumber(KFSConstants.getDashSubAccountNumber()); } if (StringUtils.isBlank(budgetConstructionRequestMove.getFinancialSubObjectCode())) { budgetConstructionRequestMove.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode()); } //set object type code Collection<String> revenueObjectTypesParamValues = BudgetParameterFinder.getRevenueObjectTypes(); Collection<String> expenditureObjectTypesParamValues = BudgetParameterFinder.getExpenditureObjectTypes(); ObjectCode objectCode = getObjectCode(budgetConstructionRequestMove, budgetYear); if (objectCode != null) { if ( expenditureObjectTypesParamValues.contains(objectCode.getFinancialObjectTypeCode()) ) { budgetConstructionRequestMove.setFinancialObjectTypeCode(objectCode.getFinancialObjectTypeCode()); // now using type from object code table //budgetConstructionRequestMove.setFinancialObjectTypeCode(optionsService.getOptions(budgetYear).getFinObjTypeExpenditureexpCd()); } else if ( revenueObjectTypesParamValues.contains(objectCode.getFinancialObjectTypeCode()) ) { budgetConstructionRequestMove.setFinancialObjectTypeCode(objectCode.getFinancialObjectTypeCode()); // now using type from object code table //budgetConstructionRequestMove.setFinancialObjectTypeCode(optionsService.getOptions(budgetYear).getFinObjectTypeIncomecashCode()); } } //check for duplicate key exception, since it requires a different error message Map searchCriteria = new HashMap(); searchCriteria.put("principalId", principalId); searchCriteria.put("chartOfAccountsCode", budgetConstructionRequestMove.getChartOfAccountsCode()); searchCriteria.put("accountNumber", budgetConstructionRequestMove.getAccountNumber()); searchCriteria.put("subAccountNumber", budgetConstructionRequestMove.getSubAccountNumber()); searchCriteria.put("financialObjectCode", budgetConstructionRequestMove.getFinancialObjectCode()); searchCriteria.put("financialSubObjectCode", budgetConstructionRequestMove.getFinancialSubObjectCode()); if ( this.businessObjectService.countMatching(BudgetConstructionRequestMove.class, searchCriteria) != 0 ) { LOG.error("Move table store error, import aborted"); fileErrorList.add("Duplicate Key for " + budgetConstructionRequestMove.getErrorLinePrefixForLogFile()); fileErrorList.add("Move table store error, import aborted"); deleteBudgetConstructionMoveRecords(principalId); return fileErrorList; } try { budgetConstructionRequestMove.setPrincipalId(principalId); importRequestDao.save(budgetConstructionRequestMove, false); } catch (RuntimeException e) { LOG.error("Move table store error, import aborted"); fileErrorList.add("Move table store error, import aborted"); return fileErrorList; } } currentLine++; } return fileErrorList; } /** * Sets the business object service * * @param businessObjectService */ @NonTransactional public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#validateData() */ @Transactional public List<String> validateData(Integer budgetYear, String principalId) { Map searchCriteria = new HashMap(); searchCriteria.put("principalId", principalId); List<BudgetConstructionRequestMove> dataToValidateList = new ArrayList<BudgetConstructionRequestMove>(businessObjectService.findMatching(BudgetConstructionRequestMove.class, searchCriteria)); List<String> errorMessages = new ArrayList<String>(); Map<String, BudgetConstructionHeader> retrievedHeaders = new HashMap<String, BudgetConstructionHeader>(); for (BudgetConstructionRequestMove record : dataToValidateList) { boolean validLine = true; //KFSMI-798 - refreshNonUpdatableReferences() used instead of refresh(), //BudgetConstructionRequestMove does not have any updatable references record.refreshNonUpdateableReferences(); String accountKey = record.getChartOfAccountsCode() + record.getAccountNumber() + record.getSubAccountNumber(); BudgetConstructionHeader budgetConstructionHeader = null; if (retrievedHeaders.containsKey(accountKey)) { budgetConstructionHeader = retrievedHeaders.get(accountKey); } else { budgetConstructionHeader = importRequestDao.getHeaderRecord(record, budgetYear); retrievedHeaders.put(accountKey, budgetConstructionHeader); } SubObjectCode subObjectCode = getSubObjectCode(record, budgetYear); String code = record.getFinancialObjectTypeCode(); LaborLedgerObject laborObject = this.laborModuleService.retrieveLaborLedgerObject(budgetYear, record.getChartOfAccountsCode(), record.getFinancialObjectCode()); ObjectCode objectCode = getObjectCode(record, budgetYear); Calendar expDate = BudgetConstructionRuleUtil.getNoBudgetAllowedExpireDate(budgetYear); if (budgetConstructionHeader == null) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_BUDGETED_ACCOUNT_SUB_ACCOUNT_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_BUDGETED_ACCOUNT_SUB_ACCOUNT_ERROR_CODE.getMessage()); } else if (!record.getAccount().isActive()) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_CLOSED_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_CLOSED_ERROR_CODE.getMessage()); } else if (record.getAccount().isExpired(expDate)) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_EXPIRED_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_EXPIRED_ERROR_CODE.getMessage()); } // invalid sub-account code NOSA else if (!record.getSubAccountNumber().equalsIgnoreCase(KFSConstants.getDashSubAccountNumber()) && ObjectUtils.isNull(record.getSubAccount())) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INVALID_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INVALID_ERROR_CODE.getMessage()); } else if (!record.getSubAccountNumber().equalsIgnoreCase(KFSConstants.getDashSubAccountNumber()) && !record.getSubAccount().isActive()) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INACTIVE_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INACTIVE_ERROR_CODE.getMessage()); } // null object type else if (StringUtils.isBlank(record.getFinancialObjectTypeCode())) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_TYPE_NULL_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_TYPE_INVALID_ERROR_CODE.getMessage()); } // inactive object code else if (objectCode != null && !objectCode.isActive()) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_CODE_INACTIVE_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_CODE_INACTIVE_ERROR_CODE.getMessage()); } // compensation object codes COMP else if (laborObject != null && (laborObject.isDetailPositionRequiredIndicator() || laborObject.getFinancialObjectFringeOrSalaryCode().equals(BCConstants.LABOR_OBJECT_FRINGE_CODE))) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_COMPENSATION_OBJECT_CODE_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_COMPENSATION_OBJECT_CODE_ERROR_CODE.getMessage()); } // no wage accounts CMPA else if (!record.getAccount().getSubFundGroup().isSubFundGroupWagesIndicator() && laborObject != null) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_WAGE_ACCOUNT_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_WAGE_ACCOUNT_ERROR_CODE.getMessage()); } // invalid sub-object code NOSO else if (!record.getFinancialSubObjectCode().equalsIgnoreCase(KFSConstants.getDashFinancialSubObjectCode()) && subObjectCode == null) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INVALID_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INVALID_ERROR_CODE.getMessage()); } // inactive sub-object code else if (!record.getFinancialSubObjectCode().equalsIgnoreCase(KFSConstants.getDashFinancialSubObjectCode()) && !subObjectCode.isActive()) { record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INACTIVE_ERROR_CODE.getErrorCode()); errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INACTIVE_ERROR_CODE.getMessage()); } importRequestDao.save(record, true); } return errorMessages; } /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#loadBudget() */ @Transactional public List<String> loadBudget(Person user, String fileType, Integer budgetYear) throws Exception { List<BudgetConstructionRequestMove> recordsToLoad = importRequestDao.findAllNonErrorCodeRecords(user.getPrincipalId()); List<String> errorMessages = new ArrayList<String>(); Map<String, BudgetConstructionRequestMove> recordMap = new HashMap<String, BudgetConstructionRequestMove>(); // month delete warning error is a soft error String deleteMonthlyWarningErrorMessage = BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getErrorCode(); for (BudgetConstructionRequestMove recordToLoad : recordsToLoad) { BudgetConstructionHeader header = importRequestDao.getHeaderRecord(recordToLoad, budgetYear); if (recordMap.containsKey(recordToLoad.getSubAccountingString())) { BudgetConstructionRequestMove temp = recordMap.get(recordToLoad.getSubAccountingString()); recordToLoad.setHasAccess(temp.getHasAccess()); recordToLoad.setHasLock(temp.getHasLock()); recordToLoad.setRequestUpdateErrorCode(temp.getRequestUpdateErrorCode()); } else { boolean hasAccess = false; if (header != null) { BudgetConstructionDocument document; try { document = (BudgetConstructionDocument) documentService.getByDocumentHeaderId(header.getDocumentNumber()); } catch (WorkflowException e) { throw new RuntimeException("Fail to retrieve budget document for doc id " + header.getDocumentNumber()); } TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(document); hasAccess = documentAuthorizer.isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId()); } if (hasAccess) { recordToLoad.setHasAccess(true); } else { recordToLoad.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_NO_ACCESS_TO_BUDGET_ACCOUNT.getErrorCode()); errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_NO_ACCESS_TO_BUDGET_ACCOUNT.getMessage()); } if (recordToLoad.getHasAccess()) { BudgetConstructionLockStatus lockStatus = this.lockService.lockAccountAndCommit(header, user.getPrincipalId()); if (lockStatus.getLockStatus().equals(BCConstants.LockStatus.SUCCESS)) { recordToLoad.setHasLock(true); } else { recordToLoad.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_BUDGET_ACCOUNT_LOCKED.getErrorCode()); errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_BUDGET_ACCOUNT_LOCKED.getMessage()); } } recordMap.put(recordToLoad.getSubAccountingString(), recordToLoad); } if (recordToLoad.getHasAccess() && recordToLoad.getHasLock() && ( StringUtils.isBlank(recordToLoad.getRequestUpdateErrorCode()) || recordToLoad.getRequestUpdateErrorCode().endsWith(deleteMonthlyWarningErrorMessage)) ) { String updateBudgetAmountErrorMessage = updateBudgetAmounts(fileType, recordToLoad, header, budgetYear); if (!StringUtils.isEmpty(updateBudgetAmountErrorMessage)) { errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + updateBudgetAmountErrorMessage); } } importRequestDao.save(recordToLoad, true); } for (String key : recordMap.keySet()) { BudgetConstructionRequestMove record = recordMap.get(key); BudgetConstructionHeader header = importRequestDao.getHeaderRecord(record, budgetYear); if (record.getHasAccess() && record.getHasLock() && ( StringUtils.isBlank(record.getRequestUpdateErrorCode()) || record.getRequestUpdateErrorCode().endsWith(deleteMonthlyWarningErrorMessage))) { udpateBenefits(fileType, header); } if (record.getHasLock() && header != null) { this.lockService.unlockAccount(header); } } deleteBudgetConstructionMoveRecords(user.getPrincipalId()); // clear ojb cache since benefits calc is done with JDBC persistenceServiceOjb.clearCache(); return errorMessages; } /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#getImportRequestDao() */ @NonTransactional public ImportRequestDao getImportRequestDao() { return this.importRequestDao; } /** * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setImportRequestDao(org.kuali.kfs.module.bc.document.dataaccess.ImportRequestDao) */ @NonTransactional public void setImportRequestDao(ImportRequestDao dao) { this.importRequestDao = dao; } /** * updates budget amounts * * @param fileType * @param importLine * @return error message */ protected String updateBudgetAmounts(String fileType, BudgetConstructionRequestMove importLine, BudgetConstructionHeader header, Integer budgetYear) { String errorMessage = ""; //set primary key values PendingBudgetConstructionGeneralLedger pendingEntry = new PendingBudgetConstructionGeneralLedger(); pendingEntry.setDocumentNumber(header.getDocumentNumber()); pendingEntry.setUniversityFiscalYear(budgetYear); pendingEntry.setChartOfAccountsCode(importLine.getChartOfAccountsCode()); pendingEntry.setAccountNumber(importLine.getAccountNumber()); pendingEntry.setSubAccountNumber(importLine.getSubAccountNumber()); pendingEntry.setFinancialObjectCode(importLine.getFinancialObjectCode()); pendingEntry.setFinancialSubObjectCode(importLine.getFinancialSubObjectCode()); pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_BASE_BUDGET); pendingEntry.setFinancialObjectTypeCode(importLine.getFinancialObjectTypeCode()); //if entry already exists, use existing entry PendingBudgetConstructionGeneralLedger retrievedPendingEntry = (PendingBudgetConstructionGeneralLedger) businessObjectService.retrieve(pendingEntry); if (retrievedPendingEntry != null) { pendingEntry = retrievedPendingEntry; } else { pendingEntry.setFinancialBeginningBalanceLineAmount(new KualiInteger(0)); } if (fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.ANNUAL.toString())) { List<BudgetConstructionMonthly> monthlyRecords = pendingEntry.getBudgetConstructionMonthly(); if (!monthlyRecords.isEmpty()) { importLine.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getErrorCode()); errorMessage = BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getMessage(); for (BudgetConstructionMonthly monthlyRecord : monthlyRecords) { businessObjectService.delete(monthlyRecord); } importRequestDao.save(importLine, true); } pendingEntry.setAccountLineAnnualBalanceAmount(importLine.getAccountLineAnnualBalanceAmount()); this.businessObjectService.save(pendingEntry); } else if (fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.MONTHLY.toString())) { //calculate account line annual balance amount KualiInteger annualAmount = new KualiInteger(0); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth1LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth2LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth3LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth4LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth5LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth6LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth7LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth8LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth9LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth10LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth11LineAmount()); annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth12LineAmount()); pendingEntry.setAccountLineAnnualBalanceAmount(annualAmount); //set primary key values BudgetConstructionMonthly monthlyEntry = new BudgetConstructionMonthly(); monthlyEntry.setDocumentNumber(header.getDocumentNumber()); monthlyEntry.setUniversityFiscalYear(budgetYear); monthlyEntry.setChartOfAccountsCode(importLine.getChartOfAccountsCode()); monthlyEntry.setAccountNumber(importLine.getAccountNumber()); monthlyEntry.setSubAccountNumber(importLine.getSubAccountNumber()); monthlyEntry.setFinancialObjectCode(importLine.getFinancialObjectCode()); monthlyEntry.setFinancialSubObjectCode(importLine.getFinancialSubObjectCode()); monthlyEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_BASE_BUDGET); monthlyEntry.setFinancialObjectTypeCode(importLine.getFinancialObjectTypeCode()); //if entry already exists, use existing entry BudgetConstructionMonthly retrievedMonthlyEntry = (BudgetConstructionMonthly) businessObjectService.retrieve(monthlyEntry); if (retrievedMonthlyEntry != null) { monthlyEntry = retrievedMonthlyEntry; //monthlyEntry.getPendingBudgetConstructionGeneralLedger().setAccountLineAnnualBalanceAmount(annualAmount); } /*else { pendingEntry.setAccountLineAnnualBalanceAmount(annualAmount); monthlyEntry.setPendingBudgetConstructionGeneralLedger(pendingEntry); }*/ monthlyEntry.setFinancialDocumentMonth1LineAmount(importLine.getFinancialDocumentMonth1LineAmount()); monthlyEntry.setFinancialDocumentMonth2LineAmount(importLine.getFinancialDocumentMonth2LineAmount()); monthlyEntry.setFinancialDocumentMonth3LineAmount(importLine.getFinancialDocumentMonth3LineAmount()); monthlyEntry.setFinancialDocumentMonth4LineAmount(importLine.getFinancialDocumentMonth4LineAmount()); monthlyEntry.setFinancialDocumentMonth5LineAmount(importLine.getFinancialDocumentMonth5LineAmount()); monthlyEntry.setFinancialDocumentMonth6LineAmount(importLine.getFinancialDocumentMonth6LineAmount()); monthlyEntry.setFinancialDocumentMonth7LineAmount(importLine.getFinancialDocumentMonth7LineAmount()); monthlyEntry.setFinancialDocumentMonth8LineAmount(importLine.getFinancialDocumentMonth8LineAmount()); monthlyEntry.setFinancialDocumentMonth9LineAmount(importLine.getFinancialDocumentMonth9LineAmount()); monthlyEntry.setFinancialDocumentMonth10LineAmount(importLine.getFinancialDocumentMonth10LineAmount()); monthlyEntry.setFinancialDocumentMonth11LineAmount(importLine.getFinancialDocumentMonth11LineAmount()); monthlyEntry.setFinancialDocumentMonth12LineAmount(importLine.getFinancialDocumentMonth12LineAmount()); this.businessObjectService.save(pendingEntry); this.businessObjectService.save(monthlyEntry); } return errorMessage; } /** * Updates benefits * * @param fileType * @param importLine */ protected void udpateBenefits(String fileType, BudgetConstructionHeader header) { BenefitsCalculationService benefitsCalculationService = SpringContext.getBean(BenefitsCalculationService.class); Map<String, Object> fieldValues = new HashMap<String, Object>(); fieldValues.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, header.getUniversityFiscalYear()); fieldValues.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, header.getChartOfAccountsCode()); fieldValues.put(KFSPropertyConstants.ACCOUNT_NUMBER, header.getAccountNumber()); fieldValues.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, header.getSubAccountNumber()); int monthlyCnt = businessObjectService.countMatching(BudgetConstructionMonthly.class, fieldValues); String sysParam = parameterService.getParameterValueAsString(KfsParameterConstants.FINANCIAL_SYSTEM_ALL.class, KFSParameterKeyConstants.LdParameterConstants.ENABLE_FRINGE_BENEFIT_CALC_BY_BENEFIT_RATE_CATEGORY_IND); // if sysParam == Y then Labor Benefit Rate Category Code must be used if (sysParam.equalsIgnoreCase("Y")) { benefitsCalculationService.calculateAnnualBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber(), header.getAccount().getLaborBenefitRateCategoryCode()); if (monthlyCnt > 0 || fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.MONTHLY.toString())) { benefitsCalculationService.calculateMonthlyBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber(), header.getAccount().getLaborBenefitRateCategoryCode()); } } else { // no rate category code - call original benefitsCalculationService.calculateAnnualBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber()); if (monthlyCnt > 0 || fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.MONTHLY.toString())) { benefitsCalculationService.calculateMonthlyBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber()); } } } /** * Checks line validations and returns error messages for line * * @param budgetConstructionRequestMove * @param lineNumber * @param isAnnual * @return */ protected String validateLine(BudgetConstructionRequestMove budgetConstructionRequestMove, int lineNumber, boolean isAnnual) { if ( !this.dictionaryValidationService.isBusinessObjectValid(budgetConstructionRequestMove)) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (isAnnual) { if (budgetConstructionRequestMove.getAccountLineAnnualBalanceAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getAccountLineAnnualBalanceAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } } if (!isAnnual) { if (budgetConstructionRequestMove.getFinancialDocumentMonth1LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth1LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth2LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth2LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth3LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth3LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth4LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth4LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth5LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth5LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth6LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth6LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth7LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth7LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth8LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth8LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth9LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth9LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth10LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth10LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth11LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth11LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } if (budgetConstructionRequestMove.getFinancialDocumentMonth12LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth12LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; } } return ""; } protected ObjectCode getObjectCode(BudgetConstructionRequestMove record, Integer budgetYear) { Map searchCriteria = new HashMap(); searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); List<ObjectCode> objectList = new ArrayList<ObjectCode>(businessObjectService.findMatching(ObjectCode.class, searchCriteria)); if (objectList.size() == 1) { return objectList.get(0); } return null; } protected SubObjectCode getSubObjectCode(BudgetConstructionRequestMove record, Integer budgetYear) { Map searchCriteria = new HashMap(); searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, record.getFinancialSubObjectCode()); List<SubObjectCode> objectList = new ArrayList<SubObjectCode> (this.businessObjectService.findMatching(SubObjectCode.class, searchCriteria)); if (objectList.size() == 1) { return objectList.get(0); } return null; } protected List<BudgetConstructionFundingLock> findBudgetLocks(BudgetConstructionRequestMove record, Integer budgetYear) { Map searchCriteria = new HashMap(); searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); searchCriteria.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, record.getSubAccountNumber()); List<BudgetConstructionFundingLock> lockList = new ArrayList<BudgetConstructionFundingLock> (this.businessObjectService.findMatching(BudgetConstructionFundingLock.class, searchCriteria)); return lockList; } List<BudgetConstructionMonthly> getMonthlyRecords(BudgetConstructionRequestMove record, BudgetConstructionHeader header) { Map searchCriteria = new HashMap(); searchCriteria.put(KFSPropertyConstants.DOCUMENT_NUMBER, header.getDocumentNumber()); searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, header.getUniversityFiscalYear()); searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); searchCriteria.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, record.getSubAccountNumber()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, record.getFinancialSubObjectCode()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE, record.getFinancialObjectTypeCode()); searchCriteria.put(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, KFSConstants.BALANCE_TYPE_BASE_BUDGET); return new ArrayList<BudgetConstructionMonthly> (this.businessObjectService.findMatching(BudgetConstructionMonthly.class, searchCriteria)); } /** * Clears BudgetConstructionRequestMove * * @param principalId */ protected void deleteBudgetConstructionMoveRecords(String principalId) { Map<String, String> fieldValues = new HashMap<String, String>(); fieldValues.put(KFSPropertyConstants.PERSON_UNIVERSAL_IDENTIFIER, principalId); businessObjectService.deleteMatching(BudgetConstructionRequestMove.class, fieldValues); } /** * * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setDictionaryValidationService(org.kuali.rice.kns.service.DictionaryValidationService) */ @NonTransactional public void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) { this.dictionaryValidationService = dictionaryValidationService; } /** * * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setLockService(org.kuali.kfs.module.bc.document.service.LockService) */ @NonTransactional public void setLockService(LockService lockService) { this.lockService = lockService; } /** * Sets BudgetDocumentService * * @param budgetDocumentService */ @NonTransactional public void setBudgetDocumentService(BudgetDocumentService budgetDocumentService) { this.budgetDocumentService = budgetDocumentService; } @NonTransactional public void setLaborModuleService(LaborModuleService laborModuleService) { this.laborModuleService = laborModuleService; } @NonTransactional public LaborModuleService getLaborModuleService() { return this.laborModuleService; } @NonTransactional public BudgetParameterService getBudgetParameterService() { return budgetParameterService; } @NonTransactional public void setBudgetParameterService(BudgetParameterService budgetParameterService) { this.budgetParameterService = budgetParameterService; } @NonTransactional public OptionsService getOptionsService() { return optionsService; } @NonTransactional public void setOptionsService(OptionsService optionsService) { this.optionsService = optionsService; } @NonTransactional public DocumentHelperService getDocumentHelperService() { return documentHelperService; } @NonTransactional public void setDocumentHelperService(DocumentHelperService documentHelperService) { this.documentHelperService = documentHelperService; } @NonTransactional protected DocumentService getDocumentService() { return documentService; } @NonTransactional public void setDocumentService(DocumentService documentService) { this.documentService = documentService; } /** * Gets the parameterService attribute. * * @return Returns the parameterService */ @NonTransactional public ParameterService getParameterService() { return parameterService; } /** * Sets the parameterService attribute. * * @param parameterService The parameterService to set. */ @NonTransactional public void setParameterService(ParameterService parameterService) { this.parameterService = parameterService; } /** * Gets the persistenceServiceOjb attribute. * * @return Returns the persistenceServiceOjb */ @NonTransactional public PersistenceService getPersistenceServiceOjb() { return persistenceServiceOjb; } /** * Sets the persistenceServiceOjb attribute. * * @param persistenceServiceOjb The persistenceServiceOjb to set. */ @NonTransactional public void setPersistenceServiceOjb(PersistenceService persistenceServiceOjb) { this.persistenceServiceOjb = persistenceServiceOjb; } }