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.endow.batch.service.impl; 017 018 import static org.kuali.kfs.module.endow.EndowConstants.NEW_SOURCE_TRAN_LINE_PROPERTY_NAME; 019 import static org.kuali.kfs.module.endow.EndowConstants.NEW_TARGET_TRAN_LINE_PROPERTY_NAME; 020 021 import java.math.BigDecimal; 022 import java.math.BigInteger; 023 import java.math.RoundingMode; 024 import java.util.ArrayList; 025 import java.util.Collection; 026 import java.util.HashMap; 027 import java.util.List; 028 import java.util.Map; 029 030 import org.kuali.kfs.module.endow.EndowConstants; 031 import org.kuali.kfs.module.endow.EndowParameterKeyConstants; 032 import org.kuali.kfs.module.endow.EndowPropertyConstants; 033 import org.kuali.kfs.module.endow.batch.CreateAutomatedCashInvestmentTransactionsStep; 034 import org.kuali.kfs.module.endow.batch.reporter.ReportDocumentStatistics; 035 import org.kuali.kfs.module.endow.batch.service.CreateAutomatedCashInvestmentTransactionsService; 036 import org.kuali.kfs.module.endow.businessobject.AutomatedCashInvestmentModel; 037 import org.kuali.kfs.module.endow.businessobject.EndowmentExceptionReportHeader; 038 import org.kuali.kfs.module.endow.businessobject.EndowmentSourceTransactionLine; 039 import org.kuali.kfs.module.endow.businessobject.EndowmentSourceTransactionSecurity; 040 import org.kuali.kfs.module.endow.businessobject.EndowmentTargetTransactionLine; 041 import org.kuali.kfs.module.endow.businessobject.EndowmentTargetTransactionSecurity; 042 import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine; 043 import org.kuali.kfs.module.endow.businessobject.HoldingTaxLot; 044 import org.kuali.kfs.module.endow.businessobject.KEMID; 045 import org.kuali.kfs.module.endow.businessobject.KemidCurrentCash; 046 import org.kuali.kfs.module.endow.businessobject.Security; 047 import org.kuali.kfs.module.endow.businessobject.TransactionDocumentExceptionReportLine; 048 import org.kuali.kfs.module.endow.businessobject.TransactionDocumentTotalReportLine; 049 import org.kuali.kfs.module.endow.dataaccess.AutomatedCashInvestmentModelDao; 050 import org.kuali.kfs.module.endow.document.AssetDecreaseDocument; 051 import org.kuali.kfs.module.endow.document.AssetIncreaseDocument; 052 import org.kuali.kfs.module.endow.document.EndowmentTaxLotLinesDocumentBase; 053 import org.kuali.kfs.module.endow.document.service.KEMIDService; 054 import org.kuali.kfs.module.endow.document.service.KEMService; 055 import org.kuali.kfs.module.endow.document.service.SecurityService; 056 import org.kuali.kfs.module.endow.document.service.UpdateAssetDecreaseDocumentTaxLotsService; 057 import org.kuali.kfs.module.endow.document.service.UpdateAssetIncreaseDocumentTaxLotsService; 058 import org.kuali.kfs.module.endow.document.validation.event.AddTransactionLineEvent; 059 import org.kuali.kfs.module.endow.util.GloabalVariablesExtractHelper; 060 import org.kuali.kfs.sys.service.ReportWriterService; 061 import org.kuali.rice.kew.exception.WorkflowException; 062 import org.kuali.rice.kns.bo.DocumentHeader; 063 import org.kuali.rice.kns.rule.event.RouteDocumentEvent; 064 import org.kuali.rice.kns.service.BusinessObjectService; 065 import org.kuali.rice.kns.service.DataDictionaryService; 066 import org.kuali.rice.kns.service.DocumentService; 067 import org.kuali.rice.kns.service.KualiConfigurationService; 068 import org.kuali.rice.kns.service.KualiRuleService; 069 import org.kuali.rice.kns.service.ParameterService; 070 import org.kuali.rice.kns.util.KualiDecimal; 071 import org.springframework.transaction.annotation.Transactional; 072 073 @Transactional 074 public class CreateAutomatedCashInvestmentTransactionsServiceImpl implements CreateAutomatedCashInvestmentTransactionsService { 075 076 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CreateAutomatedCashInvestmentTransactionsServiceImpl.class); 077 private static final String SUBMIT_DOCUMENT_DESCRIPTION = "Created by Create Automated Cash Investment Transactions Batch Process."; 078 079 private Map<String, ReportDocumentStatistics> statistics = new HashMap<String, ReportDocumentStatistics>(); 080 081 private ReportWriterService createAutomatedCashInvestmentExceptionReportWriterService; 082 private ReportWriterService createAutomatedCashInvestmentProcessedReportWriterService; 083 private UpdateAssetIncreaseDocumentTaxLotsService updateEaiTaxLotService; 084 private UpdateAssetDecreaseDocumentTaxLotsService updateEadTaxLotService; 085 private AutomatedCashInvestmentModelDao automatedCashInvestmentModelDao; 086 private BusinessObjectService businessObjectService; 087 private DataDictionaryService dataDictionaryService; 088 private KualiConfigurationService configService; 089 private KualiRuleService kualiRuleService; 090 private ParameterService parameterService; 091 private DocumentService documentService; 092 private SecurityService securityService; 093 private KEMIDService kemidService; 094 private KEMService kemService; 095 096 /** 097 * @see org.kuali.kfs.module.endow.batch.service.CreateAutomatedCashInvestmentTransactionsService#createACITransactions() 098 */ 099 public boolean createAciTransactions() { 100 101 LOG.info("Starting \"Create Automated Cash Investments Transactions\" batch job..."); 102 writeHeaders(); 103 104 for (AutomatedCashInvestmentModel aciModel : getAutomatedCashInvestmentModelMatchingCurrentDate()) { 105 106 List<KEMID> principleKemids = new ArrayList<KEMID>(kemidService.getByPrincipleAciId(aciModel.getAciModelID())); 107 List<KEMID> incomeKemids = new ArrayList<KEMID>(kemidService.getByIncomeAciId(aciModel.getAciModelID())); 108 109 // Process for increase documents. 110 processAssetIncreaseDocs(principleKemids, aciModel, false); 111 processAssetIncreaseDocs(incomeKemids, aciModel, true); 112 113 // Process for decrease documents. 114 processAssetDecreaseDocs(principleKemids, aciModel, false); 115 processAssetDecreaseDocs(incomeKemids, aciModel, true); 116 } 117 118 writeStatistics(); 119 LOG.info("Finished \"Create Automated Cash Investments Transactions\" batch job!"); 120 121 return true; 122 } 123 124 /** 125 * Process all the asset increase documents for income and principle types. 126 * 127 * @param kemid 128 * @param aciModel 129 */ 130 protected void processAssetIncreaseDocs(List<KEMID> kemids, AutomatedCashInvestmentModel aciModel, boolean isIncome) { 131 132 // An asset increase document for each of the pooled investments. 133 AssetIncreaseDocument assetIncreaseDoc1 = null; 134 AssetIncreaseDocument assetIncreaseDoc2 = null; 135 AssetIncreaseDocument assetIncreaseDoc3 = null; 136 AssetIncreaseDocument assetIncreaseDoc4 = null; 137 138 // Get the percentages. We'll only process investments with 139 // percentages greater than zero. 140 BigDecimal inv1Percent = aciModel.getInvestment1Percent(); 141 BigDecimal inv2Percent = aciModel.getInvestment2Percent(); 142 BigDecimal inv3Percent = aciModel.getInvestment3Percent(); 143 BigDecimal inv4Percent = aciModel.getInvestment4Percent(); 144 145 for (int i = 0; i < kemids.size(); i++) { 146 147 // Get the KEMID at the current index. 148 KEMID kemid = kemids.get(i); 149 150 // Get the principle/income cash equivalent. 151 BigDecimal cashEquivalent = getCashEquivalent(kemid, isIncome); 152 153 // Check if the cash equivalent is greater than zero. 154 if (cashEquivalent.compareTo(BigDecimal.ZERO) > 0) { 155 156 assetIncreaseDoc1 = processCashInvestmentForAssetIncrease(aciModel, isIncome, assetIncreaseDoc1, inv1Percent, i, kemid, cashEquivalent, 1); 157 assetIncreaseDoc2 = processCashInvestmentForAssetIncrease(aciModel, isIncome, assetIncreaseDoc2, inv2Percent, i, kemid, cashEquivalent, 2); 158 assetIncreaseDoc3 = processCashInvestmentForAssetIncrease(aciModel, isIncome, assetIncreaseDoc3, inv3Percent, i, kemid, cashEquivalent, 3); 159 assetIncreaseDoc4 = processCashInvestmentForAssetIncrease(aciModel, isIncome, assetIncreaseDoc4, inv4Percent, i, kemid, cashEquivalent, 4); 160 } 161 } 162 163 // Route documents that may still need routing. 164 performCleanUpForAssetIncrease(isIncome, assetIncreaseDoc1); 165 performCleanUpForAssetIncrease(isIncome, assetIncreaseDoc2); 166 performCleanUpForAssetIncrease(isIncome, assetIncreaseDoc3); 167 performCleanUpForAssetIncrease(isIncome, assetIncreaseDoc4); 168 } 169 170 /** 171 * Process all the asset decrease documents for income and principle types. 172 * 173 * @param kemids 174 * @param aciModel 175 * @param isIncome 176 */ 177 protected void processAssetDecreaseDocs(List<KEMID> kemids, AutomatedCashInvestmentModel aciModel, boolean isIncome) { 178 179 // An asset increase document for each of the pooled investments. 180 AssetDecreaseDocument assetDecreaseDoc1 = null; 181 AssetDecreaseDocument assetDecreaseDoc2 = null; 182 AssetDecreaseDocument assetDecreaseDoc3 = null; 183 AssetDecreaseDocument assetDecreaseDoc4 = null; 184 185 // Get the percentages. We'll only process investments with 186 // percentages greater than zero. 187 BigDecimal inv1Percent = aciModel.getInvestment1Percent(); 188 BigDecimal inv2Percent = aciModel.getInvestment2Percent(); 189 BigDecimal inv3Percent = aciModel.getInvestment3Percent(); 190 BigDecimal inv4Percent = aciModel.getInvestment4Percent(); 191 192 for (int i = 0; i < kemids.size(); i++) { 193 194 // Get the KEMID at the current index. 195 KEMID kemid = kemids.get(i); 196 197 // Get the principle/income cash equivalent. 198 BigDecimal cashEquivalent = getCashEquivalent(kemid, isIncome); 199 200 // Check if the cash equivalent is less than zero. 201 if (cashEquivalent.compareTo(BigDecimal.ZERO) < 0) { 202 203 assetDecreaseDoc1 = processCashInvestmentForAssetDecrease(aciModel, isIncome, assetDecreaseDoc1, inv1Percent, i, kemid, cashEquivalent, 1); 204 assetDecreaseDoc2 = processCashInvestmentForAssetDecrease(aciModel, isIncome, assetDecreaseDoc2, inv2Percent, i, kemid, cashEquivalent, 2); 205 assetDecreaseDoc3 = processCashInvestmentForAssetDecrease(aciModel, isIncome, assetDecreaseDoc3, inv3Percent, i, kemid, cashEquivalent, 3); 206 assetDecreaseDoc4 = processCashInvestmentForAssetDecrease(aciModel, isIncome, assetDecreaseDoc4, inv4Percent, i, kemid, cashEquivalent, 4); 207 } 208 } 209 210 // Route documents that may still need routing. 211 performCleanUpForAssetDecrease(isIncome, assetDecreaseDoc1); 212 performCleanUpForAssetDecrease(isIncome, assetDecreaseDoc2); 213 performCleanUpForAssetDecrease(isIncome, assetDecreaseDoc3); 214 performCleanUpForAssetDecrease(isIncome, assetDecreaseDoc4); 215 } 216 217 /** 218 * Verify that we don't need to do any clean-up. There could still be some let over transaction lines, less than the max amount 219 * that need to still be processed on the current eDoc. 220 * 221 * @param isIncome 222 * @param assetIncreaseDoc 223 */ 224 protected boolean performCleanUpForAssetDecrease(boolean isIncome, AssetDecreaseDocument assetDecreaseDoc) { 225 226 boolean success = false; 227 228 if (assetDecreaseDoc != null && !assetDecreaseDoc.getSourceTransactionLines().isEmpty()) { 229 // Validate and route the document. 230 success = routeAssetDecreaseDocument(assetDecreaseDoc, isIncome); 231 } 232 233 return success; 234 } 235 236 /** 237 * Verify that we don't need to do any clean-up. There could still be some let over transaction lines, less than the max amount 238 * that need to still be processed on the current eDoc. 239 * 240 * @param isIncome 241 * @param assetIncreaseDoc 242 */ 243 protected boolean performCleanUpForAssetIncrease(boolean isIncome, AssetIncreaseDocument assetIncreaseDoc) { 244 245 boolean success = false; 246 247 if (assetIncreaseDoc != null && !assetIncreaseDoc.getTargetTransactionLines().isEmpty()) { 248 // Validate and route the document. 249 success = routeAssetIncreaseDocument(assetIncreaseDoc, isIncome); 250 } 251 252 return success; 253 } 254 255 /** 256 * Helper method for processing the cash investments for asset decrease documents. 257 * 258 * @param aciModel 259 * @param isIncome 260 * @param assetDecreaseDoc 261 * @param invPercent 262 * @param i 263 * @param kemid 264 * @param cashEquivalent 265 * @param inv 266 * @return 267 */ 268 private AssetDecreaseDocument processCashInvestmentForAssetDecrease(AutomatedCashInvestmentModel aciModel, boolean isIncome, AssetDecreaseDocument assetDecreaseDoc, BigDecimal invPercent, int i, KEMID kemid, BigDecimal cashEquivalent, int inv) { 269 270 if (invPercent != null && invPercent.compareTo(BigDecimal.ZERO) != 0) { 271 String invRegistrationCode = getInvRegistrationCode(aciModel, inv); 272 String invSecurityId = getInvSecurityId(aciModel, inv); 273 274 // Initialize the asset decrease doc if null. 275 if (assetDecreaseDoc == null) { 276 assetDecreaseDoc = createAssetDecrease(invSecurityId, invRegistrationCode); 277 } 278 279 // Create, validate, and add the transaction line to the eDoc. 280 addTransactionLineForAssetDecrease(assetDecreaseDoc, aciModel, kemid.getKemid(), cashEquivalent, inv, isIncome); 281 282 // Check to see if we've reached our max number of transaction lines 283 // per eDoc. If so, validate, and submit the current eDoc and start 284 // another eDoc. 285 if ((i != 0) && (i % getMaxNumberOfTransactionLines() == 0)) { 286 // Validate and route the document. 287 routeAssetDecreaseDocument(assetDecreaseDoc, isIncome); 288 assetDecreaseDoc = createAssetDecrease(invSecurityId, invRegistrationCode); 289 } 290 } 291 292 return assetDecreaseDoc; 293 } 294 295 /** 296 * Helper method for processing the cash investments for asset increase documents. 297 * 298 * @param aciModel 299 * @param isIncome 300 * @param assetIncreaseDoc 301 * @param invPercent 302 * @param i 303 * @param kemid 304 * @param cashEquivalent 305 * @param inv 306 * @return 307 */ 308 private AssetIncreaseDocument processCashInvestmentForAssetIncrease(AutomatedCashInvestmentModel aciModel, boolean isIncome, AssetIncreaseDocument assetIncreaseDoc, BigDecimal invPercent, int i, KEMID kemid, BigDecimal cashEquivalent, int inv) { 309 310 if (invPercent != null && invPercent.compareTo(BigDecimal.ZERO) != 0) { 311 String invRegistrationCode = getInvRegistrationCode(aciModel, inv); 312 String invSecurityId = getInvSecurityId(aciModel, inv); 313 314 // Initialize the asset increase doc if null. 315 if (assetIncreaseDoc == null) { 316 assetIncreaseDoc = createAssetIncrease(invSecurityId, invRegistrationCode); 317 } 318 319 // Create, validate, and add the transaction line to the eDoc. 320 addTransactionLineForAssetIncrease(assetIncreaseDoc, aciModel, kemid.getKemid(), cashEquivalent, inv, isIncome); 321 322 // Check to see if we've reached our max number of transaction lines 323 // per eDoc. If so, validate, and submit the current eDoc and start 324 // another eDoc. 325 if ((i != 0) && (i % getMaxNumberOfTransactionLines() == 0)) { 326 // Validate and route the document. 327 routeAssetIncreaseDocument(assetIncreaseDoc, isIncome); 328 assetIncreaseDoc = createAssetIncrease(invSecurityId, invRegistrationCode); 329 } 330 } 331 332 return assetIncreaseDoc; 333 } 334 335 /** 336 * Validates the asset decrease document and routes it. 337 * 338 * @param assetDecreaseDoc 339 * @param isIncome 340 * @return 341 */ 342 protected boolean routeAssetDecreaseDocument(AssetDecreaseDocument assetDecreaseDoc, boolean isIncome) { 343 344 boolean success = false; 345 346 // Perform validation on the document. 347 boolean rulesPassed = kualiRuleService.applyRules(new RouteDocumentEvent(assetDecreaseDoc)); 348 349 // If the document passed validations, route it accordingly. 350 if (rulesPassed) { 351 boolean noRouteIndicator = getNoRouteIndicator(true); 352 try { 353 assetDecreaseDoc.setNoRouteIndicator(noRouteIndicator); 354 documentService.routeDocument(assetDecreaseDoc, SUBMIT_DOCUMENT_DESCRIPTION, null); 355 writeProcessedTableRowAssetDecrease(assetDecreaseDoc, isIncome); 356 success = true; 357 } 358 catch (WorkflowException ex) { 359 writeExceptionTableReason(assetDecreaseDoc.getDocumentNumber() + " - " + ex.getLocalizedMessage()); 360 LOG.error(ex.getLocalizedMessage()); 361 } 362 } 363 else { 364 // Write the errors to the exception file. 365 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 366 for (String errorMessage : errorMessages) { 367 writeExceptionTableReason(errorMessage); 368 } 369 // Try to save the document if it fails validation. 370 try { 371 documentService.saveDocument(assetDecreaseDoc); 372 } 373 catch (WorkflowException we) { 374 writeExceptionTableReason(assetDecreaseDoc.getDocumentNumber() + " - " + we.getLocalizedMessage()); 375 LOG.error(we.getLocalizedMessage()); 376 } 377 } 378 379 return success; 380 } 381 382 /** 383 * Validates the asset increase document and routes it. 384 * 385 * @param assetIncreaseDoc 386 * @param isIncome 387 * @return 388 */ 389 protected boolean routeAssetIncreaseDocument(AssetIncreaseDocument assetIncreaseDoc, boolean isIncome) { 390 391 boolean success = false; 392 393 // Perform validation on the document. 394 boolean rulesPassed = kualiRuleService.applyRules(new RouteDocumentEvent(assetIncreaseDoc)); 395 396 // If the document passed validations, route it accordingly. 397 if (rulesPassed) { 398 boolean noRouteIndicator = getNoRouteIndicator(false); 399 try { 400 assetIncreaseDoc.setNoRouteIndicator(noRouteIndicator); 401 documentService.routeDocument(assetIncreaseDoc, SUBMIT_DOCUMENT_DESCRIPTION, null); 402 writeProcessedTableRowAssetIncrease(assetIncreaseDoc, isIncome); 403 success = true; 404 } 405 catch (WorkflowException we) { 406 writeExceptionTableReason(assetIncreaseDoc.getDocumentNumber() + " - " + we.getLocalizedMessage()); 407 LOG.error(we.getLocalizedMessage()); 408 } 409 } 410 else { 411 // Write the errors to the exception file. 412 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 413 for (String errorMessage : errorMessages) { 414 writeExceptionTableReason(errorMessage); 415 } 416 // Try to save the document if it fails validation. 417 try { 418 documentService.saveDocument(assetIncreaseDoc); 419 } 420 catch (WorkflowException we) { 421 writeExceptionTableReason(assetIncreaseDoc.getDocumentNumber() + " - " + we.getLocalizedMessage()); 422 LOG.error(we.getLocalizedMessage()); 423 } 424 } 425 426 return success; 427 } 428 429 /** 430 * Creates a new transaction line, validates, and adds it to the asset decrease document. 431 * 432 * @param assetDecreaseDoc 433 * @param aciModel 434 * @param kemid 435 * @param cashEquivalent 436 * @param inv 437 * @param isIncome 438 */ 439 private void addTransactionLineForAssetDecrease(AssetDecreaseDocument assetDecreaseDoc, AutomatedCashInvestmentModel aciModel, String kemid, BigDecimal cashEquivalent, int inv, boolean isIncome) { 440 UnitAmountAssociation unitAmount = calculateUnitAmount(aciModel, cashEquivalent, inv); 441 442 // Create the correct transaction line based on if it's a source or target type. 443 EndowmentTransactionLine transactionLine = createTransactionLine(assetDecreaseDoc.getDocumentNumber(), kemid, aciModel.getIpIndicator(), unitAmount.getAmount(), unitAmount.getUnits(), true); 444 445 // Validate the transaction line. 446 boolean rulesPassed = kualiRuleService.applyRules(new AddTransactionLineEvent(NEW_SOURCE_TRAN_LINE_PROPERTY_NAME, assetDecreaseDoc, transactionLine)); 447 448 // If the transaction line passes validation, add it to the document. 449 if (rulesPassed) { 450 assetDecreaseDoc.addSourceTransactionLine((EndowmentSourceTransactionLine) transactionLine); 451 updateEadTaxLotService.updateTransactionLineTaxLots(assetDecreaseDoc, transactionLine); 452 } 453 else { 454 writeExceptionTableRowAssetDecrease(assetDecreaseDoc, transactionLine, isIncome); 455 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 456 for (String errorMessage : errorMessages) { 457 writeExceptionTableReason(errorMessage); 458 } 459 } 460 } 461 462 /** 463 * Creates a new transaction line, validates, and adds it to the asset increase document. 464 * 465 * @param assetIncreaseDoc 466 * @param aciModel 467 * @param cashEquivalent 468 */ 469 private void addTransactionLineForAssetIncrease(AssetIncreaseDocument assetIncreaseDoc, AutomatedCashInvestmentModel aciModel, String kemid, BigDecimal cashEquivalent, int inv, boolean isIncome) { 470 UnitAmountAssociation unitAmount = calculateUnitAmount(aciModel, cashEquivalent, inv); 471 472 // Create the correct transaction line based on if it's a source or target type. 473 EndowmentTransactionLine transactionLine = createTransactionLine(assetIncreaseDoc.getDocumentNumber(), kemid, aciModel.getIpIndicator(), unitAmount.getAmount(), unitAmount.getUnits(), false); 474 475 // Validate the transaction line. 476 boolean rulesPassed = kualiRuleService.applyRules(new AddTransactionLineEvent(NEW_TARGET_TRAN_LINE_PROPERTY_NAME, assetIncreaseDoc, transactionLine)); 477 478 // If the transaction line passes validation, add it to the document. 479 if (rulesPassed) { 480 assetIncreaseDoc.addTargetTransactionLine((EndowmentTargetTransactionLine) transactionLine); 481 updateEaiTaxLotService.updateTransactionLineTaxLots(assetIncreaseDoc, transactionLine); 482 } 483 else { 484 writeExceptionTableRowAssetIncrease(assetIncreaseDoc, transactionLine, isIncome); 485 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 486 for (String errorMessage : errorMessages) { 487 writeExceptionTableReason(errorMessage); 488 } 489 } 490 } 491 492 /** 493 * Creates a new transaction line. 494 * 495 * @param kemid 496 * @param etranCode 497 * @param amount 498 * @param units 499 * @param isSource 500 * @return 501 */ 502 private EndowmentTransactionLine createTransactionLine(String docNumber, String kemid, String ipIndicator, BigDecimal amount, BigDecimal units, boolean isSource) { 503 504 EndowmentTransactionLine transactionLine = null; 505 if (isSource) { 506 transactionLine = new EndowmentSourceTransactionLine(); 507 } 508 else { 509 transactionLine = new EndowmentTargetTransactionLine(); 510 } 511 512 // Set values on the transaction line. 513 transactionLine.setDocumentNumber(docNumber); 514 transactionLine.setKemid(kemid); 515 transactionLine.setTransactionIPIndicatorCode(ipIndicator); 516 transactionLine.setTransactionAmount(new KualiDecimal(amount)); 517 transactionLine.setTransactionUnits(new KualiDecimal(units)); 518 519 return transactionLine; 520 } 521 522 /** 523 * Get the registration code for the specified investment. 524 * 525 * @param aciModel 526 * @param inv 527 * @return 528 */ 529 private String getInvRegistrationCode(AutomatedCashInvestmentModel aciModel, int inv) { 530 531 String invRegistrationCode = ""; 532 switch (inv) { 533 case 1: 534 invRegistrationCode = aciModel.getInvestment1().getFundRegistrationCode(); 535 break; 536 case 2: 537 invRegistrationCode = aciModel.getInvestment2().getFundRegistrationCode(); 538 break; 539 case 3: 540 invRegistrationCode = aciModel.getInvestment3().getFundRegistrationCode(); 541 break; 542 case 4: 543 invRegistrationCode = aciModel.getInvestment4().getFundRegistrationCode(); 544 break; 545 } 546 547 return invRegistrationCode; 548 } 549 550 /** 551 * Get the security id from the specified investment. 552 * 553 * @param aciModel 554 * @param inv 555 * @return 556 */ 557 private String getInvSecurityId(AutomatedCashInvestmentModel aciModel, int inv) { 558 559 String invSecurityId = ""; 560 switch (inv) { 561 case 1: 562 invSecurityId = aciModel.getInvestment1SecurityID(); 563 break; 564 case 2: 565 invSecurityId = aciModel.getInvestment2SecurityID(); 566 break; 567 case 3: 568 invSecurityId = aciModel.getInvestment3SecurityID(); 569 break; 570 case 4: 571 invSecurityId = aciModel.getInvestment4SecurityID(); 572 break; 573 } 574 575 return invSecurityId; 576 } 577 578 /** 579 * Gets the correct sale offset code for the specified investment. 580 * 581 * @param aciModel 582 * @param inv 583 * @return 584 */ 585 private String getSaleOffsetCode(AutomatedCashInvestmentModel aciModel, int inv) { 586 String offsetCode = ""; 587 switch (inv) { 588 case 1: 589 offsetCode = aciModel.getInvestment1().getFundAssetSaleOffsetTranCode(); 590 break; 591 case 2: 592 offsetCode = aciModel.getInvestment2().getFundAssetSaleOffsetTranCode(); 593 break; 594 case 3: 595 offsetCode = aciModel.getInvestment3().getFundAssetSaleOffsetTranCode(); 596 break; 597 case 4: 598 offsetCode = aciModel.getInvestment4().getFundAssetSaleOffsetTranCode(); 599 break; 600 } 601 602 return offsetCode; 603 } 604 605 /** 606 * Calculates the unite amount for the specified investment. 607 * 608 * @param aciModel 609 * @param cashEquivalent 610 * @param inv 611 * @return 612 */ 613 private UnitAmountAssociation calculateUnitAmount(AutomatedCashInvestmentModel aciModel, BigDecimal cashEquivalent, int inv) { 614 615 BigDecimal invPercent = null; 616 BigDecimal invUnitValue = null; 617 BigDecimal invCashNeeded = null; 618 BigDecimal invAmount = null; 619 BigDecimal invUnits = null; 620 621 boolean allowsFractions = false; 622 623 switch (inv) { 624 case 1: 625 invPercent = aciModel.getInvestment1Percent(); 626 invUnitValue = aciModel.getInvestment1().getSecurity().getUnitValue(); 627 allowsFractions = aciModel.getInvestment1().isAllowFractionalShares(); 628 break; 629 case 2: 630 invPercent = aciModel.getInvestment2Percent(); 631 invUnitValue = aciModel.getInvestment2().getSecurity().getUnitValue(); 632 allowsFractions = aciModel.getInvestment1().isAllowFractionalShares(); 633 break; 634 case 3: 635 invPercent = aciModel.getInvestment3Percent(); 636 invUnitValue = aciModel.getInvestment3().getSecurity().getUnitValue(); 637 allowsFractions = aciModel.getInvestment1().isAllowFractionalShares(); 638 break; 639 case 4: 640 invPercent = aciModel.getInvestment4Percent(); 641 invUnitValue = aciModel.getInvestment4().getSecurity().getUnitValue(); 642 allowsFractions = aciModel.getInvestment1().isAllowFractionalShares(); 643 break; 644 } 645 646 if (invPercent != null) { 647 try { 648 invCashNeeded = new BigDecimal(invPercent.multiply(cashEquivalent).doubleValue()); 649 invUnits = invCashNeeded.divide(invUnitValue, 5, RoundingMode.HALF_UP); 650 651 if (!allowsFractions) { 652 // Round the units down. 653 invUnits = invUnits.setScale(0, BigDecimal.ROUND_DOWN); 654 } 655 invAmount = (invUnits.multiply(invUnitValue)).setScale(2, BigDecimal.ROUND_HALF_UP); 656 } 657 catch (ArithmeticException ex) { 658 writeExceptionTableReason("Caught ArithmeticException while calculating units."); 659 LOG.error("Caught exception while calculating units.", ex); 660 } 661 } 662 663 return (new UnitAmountAssociation(invAmount, invUnits)); 664 } 665 666 /** 667 * Get the max number of transaction lines allowed per document. 668 * 669 * @return 670 */ 671 private int getMaxNumberOfTransactionLines() { 672 return kemService.getMaxNumberOfTransactionLinesPerDocument(); 673 } 674 675 /** 676 * Gets the appropriate approval indicator based on if it's for a sale or purchase type. 677 * 678 * @param isSale 679 * @return 680 */ 681 private boolean getNoRouteIndicator(boolean isSale) { 682 boolean noRouteIndicator = isSale ? getSaleNoRouteIndicator() : getPurchaseNoRouteIndicator(); 683 return noRouteIndicator; 684 } 685 686 /** 687 * This method returns the true or false value of the purchase no route indicator. 688 * 689 * @return 690 */ 691 private boolean getPurchaseNoRouteIndicator() { 692 String noRouteIndicator = parameterService.getParameterValue(CreateAutomatedCashInvestmentTransactionsStep.class, EndowParameterKeyConstants.PURCHASE_NO_ROUTE_IND); 693 return (EndowConstants.YES.equalsIgnoreCase(noRouteIndicator) ? true : false); 694 } 695 696 /** 697 * This method returns the true or false value of the sale no route indicator. 698 * 699 * @return 700 */ 701 private boolean getSaleNoRouteIndicator() { 702 String noRouteIndicator = parameterService.getParameterValue(CreateAutomatedCashInvestmentTransactionsStep.class, EndowParameterKeyConstants.SALE_NO_ROUTE_IND); 703 return (EndowConstants.YES.equalsIgnoreCase(noRouteIndicator) ? true : false); 704 } 705 706 /** 707 * Creates and initializes an asset decrease document type. 708 * 709 * @param securityId 710 * @param registrationCode 711 * @return 712 */ 713 private AssetDecreaseDocument createAssetDecrease(String securityId, String registrationCode) { 714 715 AssetDecreaseDocument assetDecrease = null; 716 try { 717 assetDecrease = (AssetDecreaseDocument) documentService.getNewDocument(AssetDecreaseDocument.class); 718 719 // Set the document description. 720 DocumentHeader docHeader = assetDecrease.getDocumentHeader(); 721 docHeader.setDocumentDescription(getPurchaseDescription()); 722 assetDecrease.setDocumentHeader(docHeader); 723 724 // Set the sub type code to cash. 725 assetDecrease.setTransactionSubTypeCode(EndowConstants.TransactionSubTypeCode.CASH); 726 727 // Create and set the target security transaction line. 728 EndowmentSourceTransactionSecurity sourceTransactionSecurity = new EndowmentSourceTransactionSecurity(); 729 sourceTransactionSecurity.setSecurityLineTypeCode(EndowConstants.TRANSACTION_SECURITY_TYPE_SOURCE); 730 sourceTransactionSecurity.setRegistrationCode(registrationCode); 731 sourceTransactionSecurity.setSecurityID(securityId); 732 733 assetDecrease.setSourceTransactionSecurity(sourceTransactionSecurity); 734 } 735 catch (WorkflowException ex) { 736 writeExceptionTableReason("Workflow error while trying to create EAI document: " + ex.getLocalizedMessage()); 737 LOG.error(ex.getLocalizedMessage()); 738 } 739 740 return assetDecrease; 741 } 742 743 /** 744 * Creates and initializes an asset increase document type. 745 * 746 * @param securityId 747 * @param registrationCode 748 * @return 749 */ 750 private AssetIncreaseDocument createAssetIncrease(String securityId, String registrationCode) { 751 752 AssetIncreaseDocument assetIncrease = null; 753 try { 754 assetIncrease = (AssetIncreaseDocument) documentService.getNewDocument(AssetIncreaseDocument.class); 755 756 // Set the document description. 757 DocumentHeader docHeader = assetIncrease.getDocumentHeader(); 758 docHeader.setDocumentDescription(getPurchaseDescription()); 759 assetIncrease.setDocumentHeader(docHeader); 760 761 // Set the sub type code to cash. 762 assetIncrease.setTransactionSubTypeCode(EndowConstants.TransactionSubTypeCode.CASH); 763 764 // Create and set the target security transaction line. 765 EndowmentTargetTransactionSecurity targetTransactionSecurity = new EndowmentTargetTransactionSecurity(); 766 targetTransactionSecurity.setSecurityLineTypeCode(EndowConstants.TRANSACTION_SECURITY_TYPE_TARGET); 767 targetTransactionSecurity.setRegistrationCode(registrationCode); 768 targetTransactionSecurity.setSecurityID(securityId); 769 770 assetIncrease.setTargetTransactionSecurity(targetTransactionSecurity); 771 } 772 catch (WorkflowException ex) { 773 writeExceptionTableReason("Workflow error while trying to create EAI document: " + ex.getLocalizedMessage()); 774 LOG.error(ex.getLocalizedMessage()); 775 } 776 777 return assetIncrease; 778 } 779 780 /** 781 * Returns the appropriate principle/income cash equivalent. 782 * 783 * @param kemid 784 * @param isIncome 785 * @return BigDecimal 786 */ 787 private BigDecimal getCashEquivalent(KEMID kemid, boolean isIncome) { 788 789 BigDecimal cashEquivalent; 790 791 if (!isIncome) { 792 cashEquivalent = calculatePrincipleCashEquivalent(kemid.getKemid()); 793 } 794 else { 795 cashEquivalent = calculateIncomeCashEquivalent(kemid.getKemid()); 796 } 797 798 return cashEquivalent; 799 } 800 801 /** 802 * Calculates the total market value for cash class code. 803 * 804 * @param kemid 805 * @param ipIndicator 806 * @return 807 */ 808 private BigDecimal calculateTotalMarketValue(String kemid, String ipIndicator) { 809 810 // Used to calculate the total market value. 811 BigDecimal totalMarketValue = new BigDecimal(BigInteger.ZERO); 812 813 // Build the criteria used for getting the KEMIDs. 814 Map<String, String> map = new HashMap<String, String>(); 815 map.put(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid); 816 map.put(EndowPropertyConstants.HOLDING_TAX_LOT_INCOME_PRINCIPAL_INDICATOR, ipIndicator); 817 818 // Get all the holding tax lots that match the kemid and ipIndicator. Next, filter out 819 // those that are not cash equivalent, based on their class code type. 820 Collection<HoldingTaxLot> hldgTaxLots = businessObjectService.findMatching(HoldingTaxLot.class, map); 821 for (HoldingTaxLot hldgTaxLot : hldgTaxLots) { 822 Security security = securityService.getByPrimaryKey(hldgTaxLot.getSecurityId()); 823 if (security != null) { 824 if (security.getClassCode().getClassCodeType().equalsIgnoreCase(EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS)) { 825 totalMarketValue = totalMarketValue.add(hldgTaxLot.getUnits().multiply(security.getUnitValue())); 826 } 827 } 828 } 829 830 return totalMarketValue; 831 } 832 833 /** 834 * Calculates the principle cash equivalents. 835 * 836 * @param kemid 837 * @return 838 */ 839 private BigDecimal calculatePrincipleCashEquivalent(String kemid) { 840 BigDecimal totalMarketValue = calculateTotalMarketValue(kemid, EndowConstants.IncomePrincipalIndicator.PRINCIPAL); 841 842 return getKemidCurrentPrincipalCash(kemid).add(totalMarketValue); 843 } 844 845 /** 846 * Calculates the income cash equivalents. 847 * 848 * @param kemid 849 * @return 850 */ 851 private BigDecimal calculateIncomeCashEquivalent(String kemid) { 852 BigDecimal totalMarketValue = calculateTotalMarketValue(kemid, EndowConstants.IncomePrincipalIndicator.INCOME); 853 854 return getKemidCurrentIncomeCash(kemid).add(totalMarketValue); 855 } 856 857 /** 858 * This method... 859 * 860 * @param kemid 861 * @return 862 */ 863 private BigDecimal getKemidCurrentPrincipalCash(String kemid) { 864 KemidCurrentCash kemidCurrentCash = businessObjectService.findBySinglePrimaryKey(KemidCurrentCash.class, kemid); 865 866 if (kemidCurrentCash == null) { 867 writeExceptionTableReason("Recieved \'null\' value for END_CRNT_CSH_T for KEMID " + kemid); 868 return new BigDecimal(BigInteger.ZERO); 869 } 870 871 return kemidCurrentCash.getCurrentPrincipalCash().bigDecimalValue(); 872 } 873 874 /** 875 * This method... 876 * 877 * @param kemid 878 * @return 879 */ 880 private BigDecimal getKemidCurrentIncomeCash(String kemid) { 881 KemidCurrentCash kemidCurrentCash = businessObjectService.findBySinglePrimaryKey(KemidCurrentCash.class, kemid); 882 883 if (kemidCurrentCash == null) { 884 writeExceptionTableReason("Recieved \'null\' value for END_CRNT_CSH_T for KEMID " + kemid); 885 return new BigDecimal(BigInteger.ZERO); 886 } 887 return kemidCurrentCash.getCurrentIncomeCash().bigDecimalValue(); 888 } 889 890 /** 891 * This method retrieves all the cash sweep models whose frequency code matches the current date. 892 * 893 * @return Collection of CashSweepModel business objects 894 */ 895 private Collection<AutomatedCashInvestmentModel> getAutomatedCashInvestmentModelMatchingCurrentDate() { 896 return automatedCashInvestmentModelDao.getAutomatedCashInvestmentModelWithNextPayDateEqualToCurrentDate(kemService.getCurrentDate()); 897 } 898 899 /** 900 * This method... 901 * 902 * @param assetIncreaseDoc 903 * @param isIncome 904 */ 905 private void writeProcessedTableRowAssetIncrease(AssetIncreaseDocument assetIncreaseDoc, boolean isIncome) { 906 907 TransactionDocumentTotalReportLine createAutomatedCashInvestmentProcessedReportValues = new TransactionDocumentTotalReportLine(EndowConstants.DocumentTypeNames.ENDOWMENT_ASSET_INCREASE, assetIncreaseDoc.getDocumentNumber(), assetIncreaseDoc.getTargetTransactionSecurity().getSecurityID()); 908 909 List<EndowmentTransactionLine> transLines = assetIncreaseDoc.getTargetTransactionLines(); 910 for (EndowmentTransactionLine tranLine : transLines) { 911 if (isIncome) { 912 createAutomatedCashInvestmentProcessedReportValues.addIncomeAmount(tranLine.getTransactionAmount()); 913 createAutomatedCashInvestmentProcessedReportValues.addIncomeUnits(tranLine.getTransactionUnits()); 914 } 915 else { 916 createAutomatedCashInvestmentProcessedReportValues.addPrincipalAmount(tranLine.getTransactionAmount()); 917 createAutomatedCashInvestmentProcessedReportValues.addPrincipalUnits(tranLine.getTransactionUnits()); 918 } 919 } 920 updatePostingStats(assetIncreaseDoc); 921 922 createAutomatedCashInvestmentProcessedReportWriterService.writeTableRow(createAutomatedCashInvestmentProcessedReportValues); 923 createAutomatedCashInvestmentProcessedReportWriterService.writeNewLines(1); 924 } 925 926 /** 927 * This method... 928 * 929 * @param assetDecreaseDoc 930 * @param isIncome 931 */ 932 private void writeProcessedTableRowAssetDecrease(AssetDecreaseDocument assetDecreaseDoc, boolean isIncome) { 933 934 TransactionDocumentTotalReportLine createAutomatedCashInvestmentProcessedReportValues = new TransactionDocumentTotalReportLine(EndowConstants.DocumentTypeNames.ENDOWMENT_ASSET_DECREASE, assetDecreaseDoc.getDocumentNumber(), assetDecreaseDoc.getTargetTransactionSecurity().getSecurityID()); 935 936 List<EndowmentTransactionLine> transLines = assetDecreaseDoc.getTargetTransactionLines(); 937 for (EndowmentTransactionLine tranLine : transLines) { 938 if (isIncome) { 939 createAutomatedCashInvestmentProcessedReportValues.addIncomeAmount(tranLine.getTransactionAmount()); 940 createAutomatedCashInvestmentProcessedReportValues.addIncomeUnits(tranLine.getTransactionUnits()); 941 } 942 else { 943 createAutomatedCashInvestmentProcessedReportValues.addPrincipalAmount(tranLine.getTransactionAmount()); 944 createAutomatedCashInvestmentProcessedReportValues.addPrincipalUnits(tranLine.getTransactionUnits()); 945 } 946 } 947 updatePostingStats(assetDecreaseDoc); 948 949 createAutomatedCashInvestmentProcessedReportWriterService.writeTableRow(createAutomatedCashInvestmentProcessedReportValues); 950 createAutomatedCashInvestmentProcessedReportWriterService.writeNewLines(1); 951 } 952 953 /** 954 * This method... 955 * 956 * @param assetDecreaseDoc 957 * @param tranLine 958 * @param isIncome 959 */ 960 private void writeExceptionTableRowAssetDecrease(AssetDecreaseDocument assetDecreaseDoc, EndowmentTransactionLine tranLine, boolean isIncome) { 961 962 TransactionDocumentExceptionReportLine createAutomatedCashInvestmentExceptionReportValues = new TransactionDocumentExceptionReportLine(EndowConstants.DocumentTypeNames.ENDOWMENT_ASSET_DECREASE, assetDecreaseDoc.getDocumentNumber(), assetDecreaseDoc.getTargetTransactionSecurity().getSecurityID()); 963 964 if (tranLine != null) { 965 createAutomatedCashInvestmentExceptionReportValues.setKemid(tranLine.getKemid()); 966 if (isIncome) { 967 createAutomatedCashInvestmentExceptionReportValues.addIncomeAmount(tranLine.getTransactionAmount()); 968 createAutomatedCashInvestmentExceptionReportValues.addIncomeUnits(tranLine.getTransactionUnits()); 969 } 970 else { 971 createAutomatedCashInvestmentExceptionReportValues.addPrincipalAmount(tranLine.getTransactionAmount()); 972 createAutomatedCashInvestmentExceptionReportValues.addPrincipalUnits(tranLine.getTransactionUnits()); 973 } 974 } 975 updateErrorStats(assetDecreaseDoc); 976 977 createAutomatedCashInvestmentExceptionReportWriterService.writeTableRow(createAutomatedCashInvestmentExceptionReportValues); 978 createAutomatedCashInvestmentExceptionReportWriterService.writeNewLines(1); 979 } 980 981 /** 982 * This method... 983 * 984 * @param assetIncreaseDoc 985 * @param tranLine 986 * @param isIncome 987 */ 988 private void writeExceptionTableRowAssetIncrease(AssetIncreaseDocument assetIncreaseDoc, EndowmentTransactionLine tranLine, boolean isIncome) { 989 990 TransactionDocumentExceptionReportLine createAutomatedCashInvestmentExceptionReportValues = new TransactionDocumentExceptionReportLine(EndowConstants.DocumentTypeNames.ENDOWMENT_ASSET_INCREASE, assetIncreaseDoc.getDocumentNumber(), assetIncreaseDoc.getTargetTransactionSecurity().getSecurityID()); 991 992 if (tranLine != null) { 993 createAutomatedCashInvestmentExceptionReportValues.setKemid(tranLine.getKemid()); 994 if (isIncome) { 995 createAutomatedCashInvestmentExceptionReportValues.addIncomeAmount(tranLine.getTransactionAmount()); 996 createAutomatedCashInvestmentExceptionReportValues.addIncomeUnits(tranLine.getTransactionUnits()); 997 } 998 else { 999 createAutomatedCashInvestmentExceptionReportValues.addPrincipalAmount(tranLine.getTransactionAmount()); 1000 createAutomatedCashInvestmentExceptionReportValues.addPrincipalUnits(tranLine.getTransactionUnits()); 1001 } 1002 } 1003 updateErrorStats(assetIncreaseDoc); 1004 1005 createAutomatedCashInvestmentExceptionReportWriterService.writeTableRow(createAutomatedCashInvestmentExceptionReportValues); 1006 createAutomatedCashInvestmentExceptionReportWriterService.writeNewLines(1); 1007 } 1008 1009 /** 1010 * Writes the reason row and inserts a blank line. 1011 * 1012 * @param reasonMessage 1013 */ 1014 private void writeExceptionTableReason(String reasonMessage) { 1015 EndowmentExceptionReportHeader createAutomatedCashInvestmentExceptionReportReason = new EndowmentExceptionReportHeader(); 1016 createAutomatedCashInvestmentExceptionReportReason.setColumnHeading1("Reason: "); 1017 createAutomatedCashInvestmentExceptionReportReason.setColumnHeading2(reasonMessage); 1018 createAutomatedCashInvestmentExceptionReportWriterService.writeTableRow(createAutomatedCashInvestmentExceptionReportReason); 1019 createAutomatedCashInvestmentExceptionReportWriterService.writeNewLines(1); 1020 } 1021 1022 /** 1023 * Initialize the report document headers. 1024 */ 1025 private void writeHeaders() { 1026 createAutomatedCashInvestmentExceptionReportWriterService.writeNewLines(1); 1027 createAutomatedCashInvestmentProcessedReportWriterService.writeNewLines(1); 1028 createAutomatedCashInvestmentExceptionReportWriterService.writeTableHeader(new TransactionDocumentExceptionReportLine()); 1029 createAutomatedCashInvestmentProcessedReportWriterService.writeTableHeader(new TransactionDocumentTotalReportLine()); 1030 } 1031 1032 /** 1033 * This method... 1034 * 1035 * @param assetDocument 1036 */ 1037 private void updatePostingStats(EndowmentTaxLotLinesDocumentBase assetDocument) { 1038 1039 String documentTypeName = dataDictionaryService.getDocumentTypeNameByClass(assetDocument.getClass()); 1040 ReportDocumentStatistics stats = statistics.get(documentTypeName); 1041 1042 // If null that means there isn't one in the map, so create it and add 1043 // it to the map. 1044 if (stats == null) { 1045 stats = new ReportDocumentStatistics(documentTypeName); 1046 statistics.put(documentTypeName, stats); 1047 } 1048 stats.addNumberOfSourceTransactionLines(assetDocument.getSourceTransactionLines().size()); 1049 stats.addNumberOfTargetTransactionLines(assetDocument.getTargetTransactionLines().size()); 1050 1051 stats.incrementNumberOfDocuments(); 1052 } 1053 1054 /** 1055 * This method... 1056 * 1057 * @param assetDocument 1058 */ 1059 private void updateErrorStats(EndowmentTaxLotLinesDocumentBase assetDocument) { 1060 1061 String documentTypeName = dataDictionaryService.getDocumentTypeNameByClass(assetDocument.getClass()); 1062 ReportDocumentStatistics stats = statistics.get(documentTypeName); 1063 1064 // If null that means there isn't one in the map, so create it and add 1065 // it to the map. 1066 if (stats == null) { 1067 stats = new ReportDocumentStatistics(documentTypeName); 1068 statistics.put(documentTypeName, stats); 1069 } 1070 1071 stats.incrementNumberOfErrors(); 1072 } 1073 1074 /** 1075 * Write out the statistics. 1076 */ 1077 private void writeStatistics() { 1078 1079 for (Map.Entry<String, ReportDocumentStatistics> entry : statistics.entrySet()) { 1080 1081 ReportDocumentStatistics stats = entry.getValue(); 1082 1083 createAutomatedCashInvestmentProcessedReportWriterService.writeStatisticLine("%s Documents:", stats.getDocumentTypeName()); 1084 createAutomatedCashInvestmentProcessedReportWriterService.writeStatisticLine(" Number of Documents Generated: %d", stats.getNumberOfDocuments()); 1085 createAutomatedCashInvestmentProcessedReportWriterService.writeStatisticLine(" Number of Transaction Lines Generated: %d", stats.getTotalNumberOfTransactionLines()); 1086 createAutomatedCashInvestmentProcessedReportWriterService.writeStatisticLine(" Number of Error Records Written: %d", stats.getNumberOfErrors()); 1087 createAutomatedCashInvestmentProcessedReportWriterService.writeStatisticLine("", ""); 1088 1089 createAutomatedCashInvestmentExceptionReportWriterService.writeStatisticLine("%s Documents:", stats.getDocumentTypeName()); 1090 createAutomatedCashInvestmentExceptionReportWriterService.writeStatisticLine(" Number of Documents Generated: %d", stats.getNumberOfDocuments()); 1091 createAutomatedCashInvestmentExceptionReportWriterService.writeStatisticLine(" Number of Transaction Lines Generated: %d", stats.getTotalNumberOfTransactionLines()); 1092 createAutomatedCashInvestmentExceptionReportWriterService.writeStatisticLine(" Number of Error Records Written: %d", stats.getNumberOfErrors()); 1093 createAutomatedCashInvestmentExceptionReportWriterService.writeStatisticLine("", ""); 1094 } 1095 1096 } 1097 1098 /** 1099 * Gets the purchase description parameter. 1100 * 1101 * @return 1102 */ 1103 private String getPurchaseDescription() { 1104 return parameterService.getParameterValue(CreateAutomatedCashInvestmentTransactionsStep.class, EndowParameterKeyConstants.PURCHASE_DESCRIPTION); 1105 } 1106 1107 /** 1108 * Gets the sale description parameter. 1109 * 1110 * @return 1111 */ 1112 private String getSaleDescription() { 1113 return parameterService.getParameterValue(CreateAutomatedCashInvestmentTransactionsStep.class, EndowParameterKeyConstants.SALE_DESCRIPTION); 1114 } 1115 1116 /** 1117 * Sets the createAutomatedCashInvestmentExceptionReportWriterService attribute value. 1118 * 1119 * @param createAutomatedCashInvestmentExceptionReportWriterService The 1120 * createAutomatedCashInvestmentExceptionReportWriterService to set. 1121 */ 1122 public void setCreateAutomatedCashInvestmentExceptionReportWriterService(ReportWriterService createAutomatedCashInvestmentExceptionReportWriterService) { 1123 this.createAutomatedCashInvestmentExceptionReportWriterService = createAutomatedCashInvestmentExceptionReportWriterService; 1124 } 1125 1126 /** 1127 * Sets the createAutomatedCashInvestmentProcessedReportWriterService attribute value. 1128 * 1129 * @param createAutomatedCashInvestmentProcessedReportWriterService The 1130 * createAutomatedCashInvestmentProcessedReportWriterService to set. 1131 */ 1132 public void setCreateAutomatedCashInvestmentProcessedReportWriterService(ReportWriterService createAutomatedCashInvestmentProcessedReportWriterService) { 1133 this.createAutomatedCashInvestmentProcessedReportWriterService = createAutomatedCashInvestmentProcessedReportWriterService; 1134 } 1135 1136 /** 1137 * Sets the businessObjectService attribute value. 1138 * 1139 * @param businessObjectService The businessObjectService to set. 1140 */ 1141 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 1142 this.businessObjectService = businessObjectService; 1143 } 1144 1145 /** 1146 * Sets the kualiRuleService attribute value. 1147 * 1148 * @param kualiRuleService The kualiRuleService to set. 1149 */ 1150 public void setKualiRuleService(KualiRuleService kualiRuleService) { 1151 this.kualiRuleService = kualiRuleService; 1152 } 1153 1154 /** 1155 * Sets the parameterService attribute value. 1156 * 1157 * @param parameterService The parameterService to set. 1158 */ 1159 public void setParameterService(ParameterService parameterService) { 1160 this.parameterService = parameterService; 1161 } 1162 1163 /** 1164 * Sets the documentService attribute value. 1165 * 1166 * @param documentService The documentService to set. 1167 */ 1168 public void setDocumentService(DocumentService documentService) { 1169 this.documentService = documentService; 1170 } 1171 1172 /** 1173 * Sets the kemidService attribute value. 1174 * 1175 * @param kemidService The kemidService to set. 1176 */ 1177 public void setKemidService(KEMIDService kemidService) { 1178 this.kemidService = kemidService; 1179 } 1180 1181 /** 1182 * Sets the kemService attribute value. 1183 * 1184 * @param kemService The kemService to set. 1185 */ 1186 public void setKemService(KEMService kemService) { 1187 this.kemService = kemService; 1188 } 1189 1190 /** 1191 * Sets the securityService attribute value. 1192 * 1193 * @param securityService The securityService to set. 1194 */ 1195 public void setSecurityService(SecurityService securityService) { 1196 this.securityService = securityService; 1197 } 1198 1199 /** 1200 * Sets the configService attribute value. 1201 * 1202 * @param configService The configService to set. 1203 */ 1204 public void setConfigService(KualiConfigurationService configService) { 1205 this.configService = configService; 1206 } 1207 1208 /** 1209 * Sets the automatedCashInvestmentModelDao attribute value. 1210 * 1211 * @param automatedCashInvestmentModelDao The automatedCashInvestmentModelDao to set. 1212 */ 1213 public void setAutomatedCashInvestmentModelDao(AutomatedCashInvestmentModelDao automatedCashInvestmentModelDao) { 1214 this.automatedCashInvestmentModelDao = automatedCashInvestmentModelDao; 1215 } 1216 1217 /** 1218 * Sets the dataDictionaryService attribute value. 1219 * 1220 * @param dataDictionaryService The dataDictionaryService to set. 1221 */ 1222 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 1223 this.dataDictionaryService = dataDictionaryService; 1224 } 1225 1226 /** 1227 * Sets the updateEaiTaxLotService attribute value. 1228 * 1229 * @param updateEaiTaxLotService The updateEaiTaxLotService to set. 1230 */ 1231 public void setUpdateEaiTaxLotService(UpdateAssetIncreaseDocumentTaxLotsService updateEaiTaxLotService) { 1232 this.updateEaiTaxLotService = updateEaiTaxLotService; 1233 } 1234 1235 /** 1236 * Sets the updateEadTaxLotService attribute value. 1237 * 1238 * @param updateEadTaxLotService The updateEadTaxLotService to set. 1239 */ 1240 public void setUpdateEadTaxLotService(UpdateAssetDecreaseDocumentTaxLotsService updateEadTaxLotService) { 1241 this.updateEadTaxLotService = updateEadTaxLotService; 1242 } 1243 1244 /** 1245 * This class... 1246 */ 1247 private class UnitAmountAssociation { 1248 private BigDecimal amount; 1249 private BigDecimal units; 1250 1251 public UnitAmountAssociation(BigDecimal amount, BigDecimal units) { 1252 this.amount = amount; 1253 this.units = units; 1254 } 1255 1256 /** 1257 * Gets the amount attribute. 1258 * 1259 * @return Returns the amount. 1260 */ 1261 public BigDecimal getAmount() { 1262 return amount; 1263 } 1264 1265 /** 1266 * Gets the unit attribute. 1267 * 1268 * @return Returns the unit. 1269 */ 1270 public BigDecimal getUnits() { 1271 return units; 1272 } 1273 } 1274 }