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.module.bc.document.service.impl; 017 018 019 import java.io.BufferedReader; 020 import java.io.ByteArrayOutputStream; 021 import java.io.IOException; 022 import java.io.InputStream; 023 import java.io.InputStreamReader; 024 import java.util.ArrayList; 025 import java.util.HashMap; 026 import java.util.List; 027 import java.util.Map; 028 029 import org.apache.commons.lang.StringUtils; 030 import org.kuali.kfs.coa.businessobject.ObjectCode; 031 import org.kuali.kfs.coa.businessobject.SubObjectCode; 032 import org.kuali.kfs.integration.ld.LaborLedgerObject; 033 import org.kuali.kfs.integration.ld.LaborModuleService; 034 import org.kuali.kfs.module.bc.BCConstants; 035 import org.kuali.kfs.module.bc.BCConstants.RequestImportFileType; 036 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionFundingLock; 037 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionHeader; 038 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionLockStatus; 039 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionMonthly; 040 import org.kuali.kfs.module.bc.businessobject.BudgetConstructionRequestMove; 041 import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionGeneralLedger; 042 import org.kuali.kfs.module.bc.document.BudgetConstructionDocument; 043 import org.kuali.kfs.module.bc.document.dataaccess.ImportRequestDao; 044 import org.kuali.kfs.module.bc.document.service.BenefitsCalculationService; 045 import org.kuali.kfs.module.bc.document.service.BudgetDocumentService; 046 import org.kuali.kfs.module.bc.document.service.BudgetParameterService; 047 import org.kuali.kfs.module.bc.document.service.BudgetRequestImportService; 048 import org.kuali.kfs.module.bc.document.service.LockService; 049 import org.kuali.kfs.module.bc.util.BudgetParameterFinder; 050 import org.kuali.kfs.module.bc.util.ImportRequestFileParsingHelper; 051 import org.kuali.kfs.sys.KFSConstants; 052 import org.kuali.kfs.sys.KFSPropertyConstants; 053 import org.kuali.kfs.sys.context.SpringContext; 054 import org.kuali.kfs.sys.service.NonTransactional; 055 import org.kuali.kfs.sys.service.OptionsService; 056 import org.kuali.rice.kew.exception.WorkflowException; 057 import org.kuali.rice.kim.bo.Person; 058 import org.kuali.rice.kim.util.KimConstants; 059 import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer; 060 import org.kuali.rice.kns.service.BusinessObjectService; 061 import org.kuali.rice.kns.service.DictionaryValidationService; 062 import org.kuali.rice.kns.service.DocumentHelperService; 063 import org.kuali.rice.kns.service.DocumentService; 064 import org.kuali.rice.kns.util.KNSConstants; 065 import org.kuali.rice.kns.util.KualiInteger; 066 import org.springframework.transaction.annotation.Transactional; 067 068 import com.lowagie.text.Document; 069 import com.lowagie.text.DocumentException; 070 import com.lowagie.text.Paragraph; 071 import com.lowagie.text.pdf.PdfWriter; 072 073 /** 074 * Contains services relevent to the budget construction import request process 075 */ 076 077 public class BudgetRequestImportServiceImpl implements BudgetRequestImportService { 078 private BusinessObjectService businessObjectService; 079 private ImportRequestDao importRequestDao; 080 private DictionaryValidationService dictionaryValidationService; 081 private LockService lockService; 082 private BudgetDocumentService budgetDocumentService; 083 private LaborModuleService laborModuleService; 084 private BudgetParameterService budgetParameterService; 085 private OptionsService optionsService; 086 private DocumentHelperService documentHelperService; 087 private DocumentService documentService; 088 089 private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(BudgetRequestImportServiceImpl.class); 090 091 /** 092 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#generatePdf(java.util.List, java.io.ByteArrayOutputStream) 093 */ 094 @NonTransactional 095 public void generatePdf(List<String> errorMessages, ByteArrayOutputStream baos) throws DocumentException { 096 Document document = new Document(); 097 PdfWriter.getInstance(document, baos); 098 document.open(); 099 100 for (String error : errorMessages) { 101 document.add(new Paragraph(error)); 102 } 103 104 document.close(); 105 } 106 107 /** 108 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#processImportFile(java.io.InputStream, java.lang.String, 109 * java.lang.String, java.lang.String) 110 */ 111 @Transactional 112 public List processImportFile(InputStream fileImportStream, String principalId, String fieldSeperator, String textDelimiter, String fileType, Integer budgetYear) throws IOException { 113 List fileErrorList = new ArrayList(); 114 115 deleteBudgetConstructionMoveRecords(principalId); 116 117 BudgetConstructionRequestMove budgetConstructionRequestMove = new BudgetConstructionRequestMove(); 118 119 BufferedReader fileReader = new BufferedReader(new InputStreamReader(fileImportStream)); 120 int currentLine = 1; 121 while (fileReader.ready()) { 122 String line = StringUtils.strip(fileReader.readLine()); 123 boolean isAnnualFile = (fileType.equalsIgnoreCase(RequestImportFileType.ANNUAL.toString())) ? true : false; 124 125 if (StringUtils.isNotBlank(line)) { 126 budgetConstructionRequestMove = ImportRequestFileParsingHelper.parseLine(line, fieldSeperator, textDelimiter, isAnnualFile); 127 128 // check if there were errors parsing the line 129 if (budgetConstructionRequestMove == null) { 130 fileErrorList.add(BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + currentLine + "."); 131 // clean out table since file processing has stopped 132 deleteBudgetConstructionMoveRecords(principalId); 133 return fileErrorList; 134 } 135 136 String lineValidationError = validateLine(budgetConstructionRequestMove, currentLine, isAnnualFile); 137 138 if ( StringUtils.isNotEmpty(lineValidationError) ) { 139 fileErrorList.add(lineValidationError); 140 // clean out table since file processing has stopped 141 deleteBudgetConstructionMoveRecords(principalId); 142 return fileErrorList; 143 } 144 145 // set default values 146 if (StringUtils.isBlank(budgetConstructionRequestMove.getSubAccountNumber())) { 147 budgetConstructionRequestMove.setSubAccountNumber(KFSConstants.getDashSubAccountNumber()); 148 } 149 150 if (StringUtils.isBlank(budgetConstructionRequestMove.getFinancialSubObjectCode())) { 151 budgetConstructionRequestMove.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode()); 152 } 153 //set object type code 154 List revenueObjectTypesParamValues = BudgetParameterFinder.getRevenueObjectTypes(); 155 List expenditureObjectTypesParamValues = BudgetParameterFinder.getExpenditureObjectTypes(); 156 ObjectCode objectCode = getObjectCode(budgetConstructionRequestMove, budgetYear); 157 if (objectCode != null) { 158 if ( expenditureObjectTypesParamValues.contains(objectCode.getFinancialObjectTypeCode()) ) { 159 budgetConstructionRequestMove.setFinancialObjectTypeCode(optionsService.getOptions(budgetYear).getFinObjTypeExpenditureexpCd()); 160 } else if ( revenueObjectTypesParamValues.contains(objectCode.getFinancialObjectTypeCode()) ) { 161 budgetConstructionRequestMove.setFinancialObjectTypeCode(optionsService.getOptions(budgetYear).getFinObjectTypeIncomecashCode()); 162 } 163 } 164 165 //check for duplicate key exception, since it requires a different error message 166 Map searchCriteria = new HashMap(); 167 searchCriteria.put("principalId", principalId); 168 searchCriteria.put("chartOfAccountsCode", budgetConstructionRequestMove.getChartOfAccountsCode()); 169 searchCriteria.put("accountNumber", budgetConstructionRequestMove.getAccountNumber()); 170 searchCriteria.put("subAccountNumber", budgetConstructionRequestMove.getSubAccountNumber()); 171 searchCriteria.put("financialObjectCode", budgetConstructionRequestMove.getFinancialObjectCode()); 172 searchCriteria.put("financialSubObjectCode", budgetConstructionRequestMove.getFinancialSubObjectCode()); 173 if ( this.businessObjectService.countMatching(BudgetConstructionRequestMove.class, searchCriteria) != 0 ) { 174 LOG.error("Move table store error, import aborted"); 175 fileErrorList.add("Duplicate Key for " + budgetConstructionRequestMove.getErrorLinePrefixForLogFile()); 176 fileErrorList.add("Move table store error, import aborted"); 177 deleteBudgetConstructionMoveRecords(principalId); 178 179 return fileErrorList; 180 } 181 try { 182 budgetConstructionRequestMove.setPrincipalId(principalId); 183 importRequestDao.save(budgetConstructionRequestMove, false); 184 } 185 catch (RuntimeException e) { 186 LOG.error("Move table store error, import aborted"); 187 fileErrorList.add("Move table store error, import aborted"); 188 return fileErrorList; 189 } 190 } 191 192 currentLine++; 193 } 194 195 return fileErrorList; 196 } 197 198 199 /** 200 * Sets the business object service 201 * 202 * @param businessObjectService 203 */ 204 @NonTransactional 205 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 206 this.businessObjectService = businessObjectService; 207 } 208 209 /** 210 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#validateData() 211 */ 212 @Transactional 213 public List<String> validateData(Integer budgetYear, String principalId) { 214 Map searchCriteria = new HashMap(); 215 searchCriteria.put("principalId", principalId); 216 List<BudgetConstructionRequestMove> dataToValidateList = new ArrayList<BudgetConstructionRequestMove>(businessObjectService.findMatching(BudgetConstructionRequestMove.class, searchCriteria)); 217 List<String> errorMessages = new ArrayList<String>(); 218 219 Map<String, BudgetConstructionHeader> retrievedHeaders = new HashMap<String, BudgetConstructionHeader>(); 220 221 for (BudgetConstructionRequestMove record : dataToValidateList) { 222 boolean validLine = true; 223 //KFSMI-798 - refreshNonUpdatableReferences() used instead of refresh(), 224 //BudgetConstructionRequestMove does not have any updatable references 225 record.refreshNonUpdateableReferences(); 226 227 String accountKey = record.getChartOfAccountsCode() + record.getAccountNumber(); 228 BudgetConstructionHeader budgetConstructionHeader = null; 229 if (retrievedHeaders.containsKey(accountKey)) { 230 budgetConstructionHeader = retrievedHeaders.get(accountKey); 231 } 232 else { 233 budgetConstructionHeader = importRequestDao.getHeaderRecord(record, budgetYear); 234 retrievedHeaders.put(accountKey, budgetConstructionHeader); 235 } 236 237 SubObjectCode subObjectCode = getSubObjectCode(record, budgetYear); 238 String code = record.getFinancialObjectTypeCode(); 239 LaborLedgerObject laborObject = this.laborModuleService.retrieveLaborLedgerObject(budgetYear, record.getChartOfAccountsCode(), record.getFinancialObjectCode()); 240 ObjectCode objectCode = getObjectCode(record, budgetYear); 241 242 if (budgetConstructionHeader == null) { 243 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_BUDGETED_ACCOUNT_SUB_ACCOUNT_ERROR_CODE.getErrorCode()); 244 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_BUDGETED_ACCOUNT_SUB_ACCOUNT_ERROR_CODE.getMessage()); 245 } 246 247 else if (!record.getAccount().isActive()) { 248 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_CLOSED_ERROR_CODE.getErrorCode()); 249 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_CLOSED_ERROR_CODE.getMessage()); 250 } 251 252 else if (record.getAccount().isExpired()) { 253 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_EXPIRED_ERROR_CODE.getErrorCode()); 254 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_ACCOUNT_EXPIRED_ERROR_CODE.getMessage()); 255 } 256 257 else if (!record.getSubAccountNumber().equalsIgnoreCase(KFSConstants.getDashSubAccountNumber()) && !record.getSubAccount().isActive()) { 258 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INACTIVE_ERROR_CODE.getErrorCode()); 259 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_ACCOUNT_INACTIVE_ERROR_CODE.getMessage()); 260 } 261 262 // null object type 263 else if (StringUtils.isBlank(record.getFinancialObjectTypeCode())) { 264 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_TYPE_NULL_ERROR_CODE.getErrorCode()); 265 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_TYPE_INVALID_ERROR_CODE.getMessage()); 266 } 267 268 // inactive object code 269 else if (objectCode != null && !objectCode.isActive()) { 270 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_CODE_INACTIVE_ERROR_CODE.getErrorCode()); 271 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_OBJECT_CODE_INACTIVE_ERROR_CODE.getMessage()); 272 } 273 274 // compensation object codes COMP 275 else if (laborObject != null && (laborObject.isDetailPositionRequiredIndicator() || laborObject.getFinancialObjectFringeOrSalaryCode().equals(BCConstants.LABOR_OBJECT_FRINGE_CODE))) { 276 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_COMPENSATION_OBJECT_CODE_ERROR_CODE.getErrorCode()); 277 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_COMPENSATION_OBJECT_CODE_ERROR_CODE.getMessage()); 278 } 279 280 // no wage accounts CMPA 281 else if (!record.getAccount().getSubFundGroup().isSubFundGroupWagesIndicator() && laborObject != null) { 282 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_WAGE_ACCOUNT_ERROR_CODE.getErrorCode()); 283 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_NO_WAGE_ACCOUNT_ERROR_CODE.getMessage()); 284 } 285 286 // invalid sub-object code NOSO 287 else if (!record.getFinancialSubObjectCode().equalsIgnoreCase(KFSConstants.getDashFinancialSubObjectCode()) && subObjectCode == null) { 288 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INVALID_ERROR_CODE.getErrorCode()); 289 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INVALID_ERROR_CODE.getMessage()); 290 } 291 292 // inactive sub-object code 293 else if (!record.getFinancialSubObjectCode().equalsIgnoreCase(KFSConstants.getDashFinancialSubObjectCode()) && !subObjectCode.isActive()) { 294 record.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INACTIVE_ERROR_CODE.getErrorCode()); 295 errorMessages.add(record.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.DATA_VALIDATION_SUB_OBJECT_INACTIVE_ERROR_CODE.getMessage()); 296 } 297 298 importRequestDao.save(record, true); 299 } 300 301 return errorMessages; 302 } 303 304 /** 305 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#loadBudget() 306 */ 307 @Transactional 308 public List<String> loadBudget(Person user, String fileType, Integer budgetYear) throws Exception { 309 List<BudgetConstructionRequestMove> recordsToLoad = importRequestDao.findAllNonErrorCodeRecords(user.getPrincipalId()); 310 List<String> errorMessages = new ArrayList<String>(); 311 Map<String, BudgetConstructionRequestMove> recordMap = new HashMap<String, BudgetConstructionRequestMove>(); 312 313 for (BudgetConstructionRequestMove recordToLoad : recordsToLoad) { 314 BudgetConstructionHeader header = importRequestDao.getHeaderRecord(recordToLoad, budgetYear); 315 316 if (recordMap.containsKey(recordToLoad.getSubAccountingString())) { 317 BudgetConstructionRequestMove temp = recordMap.get(recordToLoad.getSubAccountingString()); 318 319 recordToLoad.setHasAccess(temp.getHasAccess()); 320 recordToLoad.setHasLock(temp.getHasLock()); 321 recordToLoad.setRequestUpdateErrorCode(temp.getRequestUpdateErrorCode()); 322 } 323 else { 324 boolean hasAccess = false; 325 if (header != null) { 326 BudgetConstructionDocument document; 327 try { 328 document = (BudgetConstructionDocument) documentService.getByDocumentHeaderId(header.getDocumentNumber()); 329 } 330 catch (WorkflowException e) { 331 throw new RuntimeException("Fail to retrieve budget document for doc id " + header.getDocumentNumber()); 332 } 333 334 TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(document); 335 hasAccess = documentAuthorizer.isAuthorizedByTemplate(document, KNSConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId()); 336 } 337 338 if (hasAccess) { 339 recordToLoad.setHasAccess(true); 340 } 341 else { 342 recordToLoad.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_NO_ACCESS_TO_BUDGET_ACCOUNT.getErrorCode()); 343 errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_NO_ACCESS_TO_BUDGET_ACCOUNT.getMessage()); 344 } 345 346 if (recordToLoad.getHasAccess()) { 347 BudgetConstructionLockStatus lockStatus = this.lockService.lockAccountAndCommit(header, user.getPrincipalId()); 348 if (lockStatus.getLockStatus().equals(BCConstants.LockStatus.SUCCESS)) { 349 recordToLoad.setHasLock(true); 350 } else { 351 recordToLoad.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_BUDGET_ACCOUNT_LOCKED.getErrorCode()); 352 errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_BUDGET_ACCOUNT_LOCKED.getMessage()); 353 } 354 } 355 356 recordMap.put(recordToLoad.getSubAccountingString(), recordToLoad); 357 } 358 359 //since error codes are copied based on the locking key, the previous records error code from the updateBudgetAmounts may have been copied to this record and should be ignored. 360 String updateAmountPreviousErrorMessage =BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getErrorCode(); 361 if (recordToLoad.getHasAccess() && recordToLoad.getHasLock() && 362 ( StringUtils.isBlank(recordToLoad.getRequestUpdateErrorCode()) || recordToLoad.getRequestUpdateErrorCode().endsWith(updateAmountPreviousErrorMessage)) ) { 363 String updateBudgetAmountErrorMessage = updateBudgetAmounts(fileType, recordToLoad, header, budgetYear); 364 if (!StringUtils.isEmpty(updateBudgetAmountErrorMessage)) 365 errorMessages.add(recordToLoad.getErrorLinePrefixForLogFile() + " " + updateBudgetAmountErrorMessage); 366 } 367 368 importRequestDao.save(recordToLoad, true); 369 } 370 371 for (String key : recordMap.keySet()) { 372 BudgetConstructionRequestMove record = recordMap.get(key); 373 BudgetConstructionHeader header = importRequestDao.getHeaderRecord(record, budgetYear); 374 if (record.getHasAccess() && record.getHasLock() && StringUtils.isBlank(record.getRequestUpdateErrorCode())) { 375 udpateBenefits(fileType, header); 376 } 377 378 if (record.getHasLock() && header != null) { 379 this.lockService.unlockAccount(header); 380 } 381 } 382 383 deleteBudgetConstructionMoveRecords(user.getPrincipalId()); 384 return errorMessages; 385 } 386 387 /** 388 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#getImportRequestDao() 389 */ 390 @NonTransactional 391 public ImportRequestDao getImportRequestDao() { 392 return this.importRequestDao; 393 } 394 395 /** 396 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setImportRequestDao(org.kuali.kfs.module.bc.document.dataaccess.ImportRequestDao) 397 */ 398 @NonTransactional 399 public void setImportRequestDao(ImportRequestDao dao) { 400 this.importRequestDao = dao; 401 402 } 403 404 /** 405 * updates budget amounts 406 * 407 * @param fileType 408 * @param importLine 409 * @return error message 410 */ 411 protected String updateBudgetAmounts(String fileType, BudgetConstructionRequestMove importLine, BudgetConstructionHeader header, Integer budgetYear) { 412 String errorMessage = ""; 413 414 //set primary key values 415 PendingBudgetConstructionGeneralLedger pendingEntry = new PendingBudgetConstructionGeneralLedger(); 416 pendingEntry.setDocumentNumber(header.getDocumentNumber()); 417 pendingEntry.setUniversityFiscalYear(budgetYear); 418 pendingEntry.setChartOfAccountsCode(importLine.getChartOfAccountsCode()); 419 pendingEntry.setAccountNumber(importLine.getAccountNumber()); 420 pendingEntry.setSubAccountNumber(importLine.getSubAccountNumber()); 421 pendingEntry.setFinancialObjectCode(importLine.getFinancialObjectCode()); 422 pendingEntry.setFinancialSubObjectCode(importLine.getFinancialSubObjectCode()); 423 pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_BASE_BUDGET); 424 pendingEntry.setFinancialObjectTypeCode(importLine.getFinancialObjectTypeCode()); 425 426 //if entry already exists, use existing entry 427 PendingBudgetConstructionGeneralLedger retrievedPendingEntry = (PendingBudgetConstructionGeneralLedger) businessObjectService.retrieve(pendingEntry); 428 if (retrievedPendingEntry != null) pendingEntry = retrievedPendingEntry; 429 else pendingEntry.setFinancialBeginningBalanceLineAmount(new KualiInteger(0)); 430 431 if (fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.ANNUAL.toString())) { 432 List<BudgetConstructionMonthly> monthlyRecords = pendingEntry.getBudgetConstructionMonthly(); 433 434 if (!monthlyRecords.isEmpty()) { 435 importLine.setRequestUpdateErrorCode(BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getErrorCode()); 436 errorMessage = BCConstants.RequestImportErrorCode.UPDATE_ERROR_CODE_MONTHLY_BUDGET_DELETED.getMessage(); 437 for (BudgetConstructionMonthly monthlyRecord : monthlyRecords) { 438 businessObjectService.delete(monthlyRecord); 439 } 440 441 importRequestDao.save(importLine, true); 442 } 443 444 pendingEntry.setAccountLineAnnualBalanceAmount(importLine.getAccountLineAnnualBalanceAmount()); 445 this.businessObjectService.save(pendingEntry); 446 } 447 else if (fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.MONTHLY.toString())) { 448 449 //calculate account line annual balance amount 450 KualiInteger annualAmount = new KualiInteger(0); 451 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth1LineAmount()); 452 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth2LineAmount()); 453 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth3LineAmount()); 454 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth4LineAmount()); 455 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth5LineAmount()); 456 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth6LineAmount()); 457 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth7LineAmount()); 458 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth8LineAmount()); 459 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth9LineAmount()); 460 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth10LineAmount()); 461 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth11LineAmount()); 462 annualAmount = annualAmount.add(importLine.getFinancialDocumentMonth12LineAmount()); 463 pendingEntry.setAccountLineAnnualBalanceAmount(annualAmount); 464 465 466 //set primary key values 467 BudgetConstructionMonthly monthlyEntry = new BudgetConstructionMonthly(); 468 monthlyEntry.setDocumentNumber(header.getDocumentNumber()); 469 monthlyEntry.setUniversityFiscalYear(budgetYear); 470 monthlyEntry.setChartOfAccountsCode(importLine.getChartOfAccountsCode()); 471 monthlyEntry.setAccountNumber(importLine.getAccountNumber()); 472 monthlyEntry.setSubAccountNumber(importLine.getSubAccountNumber()); 473 monthlyEntry.setFinancialObjectCode(importLine.getFinancialObjectCode()); 474 monthlyEntry.setFinancialSubObjectCode(importLine.getFinancialSubObjectCode()); 475 monthlyEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_BASE_BUDGET); 476 monthlyEntry.setFinancialObjectTypeCode(importLine.getFinancialObjectTypeCode()); 477 478 //if entry already exists, use existing entry 479 BudgetConstructionMonthly retrievedMonthlyEntry = (BudgetConstructionMonthly) businessObjectService.retrieve(monthlyEntry); 480 if (retrievedMonthlyEntry != null) { 481 monthlyEntry = retrievedMonthlyEntry; 482 //monthlyEntry.getPendingBudgetConstructionGeneralLedger().setAccountLineAnnualBalanceAmount(annualAmount); 483 } 484 /*else { 485 pendingEntry.setAccountLineAnnualBalanceAmount(annualAmount); 486 monthlyEntry.setPendingBudgetConstructionGeneralLedger(pendingEntry); 487 }*/ 488 489 monthlyEntry.setFinancialDocumentMonth1LineAmount(importLine.getFinancialDocumentMonth1LineAmount()); 490 monthlyEntry.setFinancialDocumentMonth2LineAmount(importLine.getFinancialDocumentMonth2LineAmount()); 491 monthlyEntry.setFinancialDocumentMonth3LineAmount(importLine.getFinancialDocumentMonth3LineAmount()); 492 monthlyEntry.setFinancialDocumentMonth4LineAmount(importLine.getFinancialDocumentMonth4LineAmount()); 493 monthlyEntry.setFinancialDocumentMonth5LineAmount(importLine.getFinancialDocumentMonth5LineAmount()); 494 monthlyEntry.setFinancialDocumentMonth6LineAmount(importLine.getFinancialDocumentMonth6LineAmount()); 495 monthlyEntry.setFinancialDocumentMonth7LineAmount(importLine.getFinancialDocumentMonth7LineAmount()); 496 monthlyEntry.setFinancialDocumentMonth8LineAmount(importLine.getFinancialDocumentMonth8LineAmount()); 497 monthlyEntry.setFinancialDocumentMonth9LineAmount(importLine.getFinancialDocumentMonth9LineAmount()); 498 monthlyEntry.setFinancialDocumentMonth10LineAmount(importLine.getFinancialDocumentMonth10LineAmount()); 499 monthlyEntry.setFinancialDocumentMonth11LineAmount(importLine.getFinancialDocumentMonth11LineAmount()); 500 monthlyEntry.setFinancialDocumentMonth12LineAmount(importLine.getFinancialDocumentMonth12LineAmount()); 501 502 this.businessObjectService.save(pendingEntry); 503 this.businessObjectService.save(monthlyEntry); 504 505 } 506 507 return errorMessage; 508 } 509 510 /** 511 * Updates benefits 512 * 513 * @param fileType 514 * @param importLine 515 */ 516 protected void udpateBenefits(String fileType, BudgetConstructionHeader header) { 517 BenefitsCalculationService benefitsCalculationService = SpringContext.getBean(BenefitsCalculationService.class); 518 519 benefitsCalculationService.calculateAnnualBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber()); 520 521 if (fileType.equalsIgnoreCase(BCConstants.RequestImportFileType.MONTHLY.toString())) { 522 benefitsCalculationService.calculateMonthlyBudgetConstructionGeneralLedgerBenefits(header.getDocumentNumber(), header.getUniversityFiscalYear(), header.getChartOfAccountsCode(), header.getAccountNumber(), header.getSubAccountNumber()); 523 } 524 } 525 526 /** 527 * Checks line validations and returns error messages for line 528 * 529 * @param budgetConstructionRequestMove 530 * @param lineNumber 531 * @param isAnnual 532 * @return 533 */ 534 535 protected String validateLine(BudgetConstructionRequestMove budgetConstructionRequestMove, int lineNumber, boolean isAnnual) { 536 537 if ( !this.dictionaryValidationService.isBusinessObjectValid(budgetConstructionRequestMove)) { 538 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 539 } 540 541 if (isAnnual) { 542 if (budgetConstructionRequestMove.getAccountLineAnnualBalanceAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getAccountLineAnnualBalanceAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 543 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 544 } 545 } 546 547 if (!isAnnual) { 548 549 if (budgetConstructionRequestMove.getFinancialDocumentMonth1LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth1LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 550 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 551 } 552 if (budgetConstructionRequestMove.getFinancialDocumentMonth2LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth2LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 553 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 554 } 555 if (budgetConstructionRequestMove.getFinancialDocumentMonth3LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth3LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 556 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 557 } 558 if (budgetConstructionRequestMove.getFinancialDocumentMonth4LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth4LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 559 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 560 } 561 if (budgetConstructionRequestMove.getFinancialDocumentMonth5LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth5LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 562 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 563 } 564 if (budgetConstructionRequestMove.getFinancialDocumentMonth6LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth6LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 565 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 566 } 567 if (budgetConstructionRequestMove.getFinancialDocumentMonth7LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth7LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 568 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 569 } 570 if (budgetConstructionRequestMove.getFinancialDocumentMonth8LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth8LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 571 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 572 } 573 if (budgetConstructionRequestMove.getFinancialDocumentMonth9LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth9LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 574 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 575 } 576 if (budgetConstructionRequestMove.getFinancialDocumentMonth10LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth10LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 577 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 578 } 579 if (budgetConstructionRequestMove.getFinancialDocumentMonth11LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth11LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 580 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 581 } 582 if (budgetConstructionRequestMove.getFinancialDocumentMonth12LineAmount().compareTo(new KualiInteger(999999999)) >= 0 || budgetConstructionRequestMove.getFinancialDocumentMonth12LineAmount().compareTo(new KualiInteger(-999999999)) <= 0) { 583 return BCConstants.REQUEST_IMPORT_FILE_PROCESSING_ERROR_MESSAGE_GENERIC + " " + lineNumber + "."; 584 } 585 } 586 587 return ""; 588 } 589 590 protected ObjectCode getObjectCode(BudgetConstructionRequestMove record, Integer budgetYear) { 591 Map searchCriteria = new HashMap(); 592 593 searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); 594 searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); 595 searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); 596 597 List<ObjectCode> objectList = new ArrayList<ObjectCode>(businessObjectService.findMatching(ObjectCode.class, searchCriteria)); 598 599 if (objectList.size() == 1) 600 return objectList.get(0); 601 602 return null; 603 } 604 605 protected SubObjectCode getSubObjectCode(BudgetConstructionRequestMove record, Integer budgetYear) { 606 Map searchCriteria = new HashMap(); 607 608 searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); 609 searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); 610 searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); 611 searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); 612 searchCriteria.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, record.getFinancialSubObjectCode()); 613 614 List<SubObjectCode> objectList = new ArrayList<SubObjectCode> (this.businessObjectService.findMatching(SubObjectCode.class, searchCriteria)); 615 616 if (objectList.size() == 1) 617 return objectList.get(0); 618 619 return null; 620 } 621 622 protected List<BudgetConstructionFundingLock> findBudgetLocks(BudgetConstructionRequestMove record, Integer budgetYear) { 623 Map searchCriteria = new HashMap(); 624 625 searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, budgetYear); 626 searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); 627 searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); 628 searchCriteria.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, record.getSubAccountNumber()); 629 630 List<BudgetConstructionFundingLock> lockList = new ArrayList<BudgetConstructionFundingLock> (this.businessObjectService.findMatching(BudgetConstructionFundingLock.class, searchCriteria)); 631 632 return lockList; 633 } 634 635 List<BudgetConstructionMonthly> getMonthlyRecords(BudgetConstructionRequestMove record, BudgetConstructionHeader header) { 636 Map searchCriteria = new HashMap(); 637 638 searchCriteria.put(KFSPropertyConstants.DOCUMENT_NUMBER, header.getDocumentNumber()); 639 searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, header.getUniversityFiscalYear()); 640 searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, record.getChartOfAccountsCode()); 641 searchCriteria.put(KFSPropertyConstants.ACCOUNT_NUMBER, record.getAccountNumber()); 642 searchCriteria.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, record.getSubAccountNumber()); 643 searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, record.getFinancialObjectCode()); 644 searchCriteria.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, record.getFinancialSubObjectCode()); 645 searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE, record.getFinancialObjectTypeCode()); 646 searchCriteria.put(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, KFSConstants.BALANCE_TYPE_BASE_BUDGET); 647 648 return new ArrayList<BudgetConstructionMonthly> (this.businessObjectService.findMatching(BudgetConstructionMonthly.class, searchCriteria)); 649 } 650 651 /** 652 * Clears BudgetConstructionRequestMove 653 * 654 * @param principalId 655 */ 656 protected void deleteBudgetConstructionMoveRecords(String principalId) { 657 Map<String, String> fieldValues = new HashMap<String, String>(); 658 fieldValues.put(KFSPropertyConstants.PERSON_UNIVERSAL_IDENTIFIER, principalId); 659 businessObjectService.deleteMatching(BudgetConstructionRequestMove.class, fieldValues); 660 } 661 662 /** 663 * 664 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setDictionaryValidationService(org.kuali.rice.kns.service.DictionaryValidationService) 665 */ 666 @NonTransactional 667 public void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) { 668 this.dictionaryValidationService = dictionaryValidationService; 669 670 } 671 672 /** 673 * 674 * @see org.kuali.kfs.module.bc.document.service.BudgetRequestImportService#setLockService(org.kuali.kfs.module.bc.document.service.LockService) 675 */ 676 @NonTransactional 677 public void setLockService(LockService lockService) { 678 this.lockService = lockService; 679 } 680 681 /** 682 * Sets BudgetDocumentService 683 * 684 * @param budgetDocumentService 685 */ 686 @NonTransactional 687 public void setBudgetDocumentService(BudgetDocumentService budgetDocumentService) { 688 this.budgetDocumentService = budgetDocumentService; 689 } 690 691 @NonTransactional 692 public void setLaborModuleService(LaborModuleService laborModuleService) { 693 this.laborModuleService = laborModuleService; 694 } 695 696 @NonTransactional 697 public LaborModuleService getLaborModuleService() { 698 return this.laborModuleService; 699 } 700 701 @NonTransactional 702 public BudgetParameterService getBudgetParameterService() { 703 return budgetParameterService; 704 } 705 706 @NonTransactional 707 public void setBudgetParameterService(BudgetParameterService budgetParameterService) { 708 this.budgetParameterService = budgetParameterService; 709 } 710 711 @NonTransactional 712 public OptionsService getOptionsService() { 713 return optionsService; 714 } 715 716 @NonTransactional 717 public void setOptionsService(OptionsService optionsService) { 718 this.optionsService = optionsService; 719 } 720 721 @NonTransactional 722 public DocumentHelperService getDocumentHelperService() { 723 return documentHelperService; 724 } 725 726 @NonTransactional 727 public void setDocumentHelperService(DocumentHelperService documentHelperService) { 728 this.documentHelperService = documentHelperService; 729 } 730 731 @NonTransactional 732 protected DocumentService getDocumentService() { 733 return documentService; 734 } 735 736 @NonTransactional 737 public void setDocumentService(DocumentService documentService) { 738 this.documentService = documentService; 739 } 740 741 } 742