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.util.ArrayList; 022 import java.util.HashMap; 023 import java.util.List; 024 import java.util.Map; 025 026 import org.kuali.kfs.module.endow.EndowConstants; 027 import org.kuali.kfs.module.endow.EndowParameterKeyConstants; 028 import org.kuali.kfs.module.endow.batch.CreateGainLossDistributionTransactionsStep; 029 import org.kuali.kfs.module.endow.batch.service.CreateGainLossDistributionTransactionsService; 030 import org.kuali.kfs.module.endow.businessobject.EndowmentExceptionReportHeader; 031 import org.kuali.kfs.module.endow.businessobject.EndowmentSourceTransactionLine; 032 import org.kuali.kfs.module.endow.businessobject.EndowmentSourceTransactionSecurity; 033 import org.kuali.kfs.module.endow.businessobject.EndowmentTargetTransactionLine; 034 import org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine; 035 import org.kuali.kfs.module.endow.businessobject.GainLossDistributionTotalReportLine; 036 import org.kuali.kfs.module.endow.businessobject.HoldingTaxLot; 037 import org.kuali.kfs.module.endow.businessobject.PooledFundValue; 038 import org.kuali.kfs.module.endow.businessobject.TransactionDocumentExceptionReportLine; 039 import org.kuali.kfs.module.endow.document.HoldingAdjustmentDocument; 040 import org.kuali.kfs.module.endow.document.service.HoldingTaxLotService; 041 import org.kuali.kfs.module.endow.document.service.KEMService; 042 import org.kuali.kfs.module.endow.document.service.PooledFundValueService; 043 import org.kuali.kfs.module.endow.document.service.UpdateHoldingAdjustmentDocumentTaxLotsService; 044 import org.kuali.kfs.module.endow.document.validation.event.AddTransactionLineEvent; 045 import org.kuali.kfs.module.endow.util.GloabalVariablesExtractHelper; 046 import org.kuali.kfs.sys.KFSConstants; 047 import org.kuali.kfs.sys.service.ReportWriterService; 048 import org.kuali.rice.kew.exception.WorkflowException; 049 import org.kuali.rice.kns.rule.event.RouteDocumentEvent; 050 import org.kuali.rice.kns.service.BusinessObjectService; 051 import org.kuali.rice.kns.service.DocumentService; 052 import org.kuali.rice.kns.service.KualiConfigurationService; 053 import org.kuali.rice.kns.service.KualiRuleService; 054 import org.kuali.rice.kns.service.ParameterService; 055 import org.kuali.rice.kns.util.ObjectUtils; 056 import org.springframework.transaction.annotation.Transactional; 057 058 @Transactional 059 public class CreateGainLossDistributionTransactionsServiceImpl implements CreateGainLossDistributionTransactionsService { 060 061 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CreateGainLossDistributionTransactionsServiceImpl.class); 062 063 private PooledFundValueService pooledFundValueService; 064 private HoldingTaxLotService holdingTaxLotService; 065 private DocumentService documentService; 066 private ParameterService parameterService; 067 private KualiConfigurationService configService; 068 private KualiRuleService kualiRuleService; 069 private BusinessObjectService businessObjectService; 070 private UpdateHoldingAdjustmentDocumentTaxLotsService updateHoldingAdjustmentDocumentTaxLotsService; 071 private KEMService kemService; 072 073 private ReportWriterService gainLossDistributionExceptionReportWriterService; 074 private ReportWriterService gainLossDistributionTotalsReportWriterService; 075 076 private EndowmentExceptionReportHeader gainLossDistributionExceptionRowReason; 077 private GainLossDistributionTotalReportLine distributionTotalReportLine; 078 private TransactionDocumentExceptionReportLine exceptionReportLine; 079 080 private boolean isFistTimeForWritingTotalReport = true; 081 private boolean isFistTimeForWritingExceptionReport = true; 082 083 /** 084 * Constructs a CreateGainLossDistributionTransactionsServiceImpl.java. 085 */ 086 public CreateGainLossDistributionTransactionsServiceImpl() { 087 gainLossDistributionExceptionRowReason = new EndowmentExceptionReportHeader(); 088 } 089 090 /** 091 * @see org.kuali.kfs.module.endow.batch.service.CreateGainLossDistributionTransactionsService#processGainLossDistribution() 092 */ 093 public boolean processGainLossDistribution() { 094 boolean result = true; 095 096 LOG.debug("processGainLossDistribution() started"); 097 098 // process short term gain/loss 099 result &= processShortTermGainLossDistribution(); 100 101 // process long term gain/loss 102 result &= processLongTermGainLossDistribution(); 103 104 return result; 105 } 106 107 /** 108 * Processes Short Term Gains and Losses. 109 * 110 * @return true if successful, false otherwise 111 */ 112 protected boolean processShortTermGainLossDistribution() { 113 return processGainLossDistribution(true); 114 } 115 116 /** 117 * Processes Long Term Gains and Losses. 118 * 119 * @return true if successful, false otherwise 120 */ 121 protected boolean processLongTermGainLossDistribution() { 122 return processGainLossDistribution(false); 123 } 124 125 126 /** 127 * Processes Short/Long Term Gains and Losses. 128 * 129 * @return true if successful, false otherwise 130 */ 131 protected boolean processGainLossDistribution(boolean isShortTerm) { 132 boolean result = true; 133 List<PooledFundValue> pooledFundValues = null; 134 int maxNumberOfTranLines = kemService.getMaxNumberOfTransactionLinesPerDocument(); 135 136 // process gain/loss 137 138 if (isShortTerm) { 139 // 1. collect all PooledFundValue entries with ST_PROC_ON_DT equal to current date 140 pooledFundValues = pooledFundValueService.getPooledFundValueWhereSTProcessOnDateIsCurrentDate(); 141 } 142 else { 143 // 1. collect all PooledFundValue entries with LT_PROC_ON_DT equal to current date 144 pooledFundValues = pooledFundValueService.getPooledFundValueWhereLTProcessOnDateIsCurrentDate(); 145 } 146 147 for (PooledFundValue pooledFundValue : pooledFundValues) { 148 // 3. get all tax lots with security ID equal to pooledSecurityId 149 List<HoldingTaxLot> holdingTaxLots = holdingTaxLotService.getTaxLotsPerSecurityIDWithUnitsGreaterThanZero(pooledFundValue.getPooledSecurityID()); 150 151 // group by registration code 152 if (holdingTaxLots != null) { 153 // a map from registration code to taxlots 154 Map<String, List<HoldingTaxLot>> regCodeMap = groupTaxLotsByRegistrationCode(holdingTaxLots); 155 156 // for each security and registration code generate a new HoldingAdjustmentDocument 157 158 for (String registrationCode : regCodeMap.keySet()) { 159 160 List<HoldingTaxLot> taxLots = regCodeMap.get(registrationCode); 161 // 4. generate Holding Adjustment document 162 HoldingAdjustmentDocument holdingAdjustmentDocument = generateHoldingAdjustmentDocument(isShortTerm, pooledFundValue.getPooledSecurityID()); 163 164 if (holdingAdjustmentDocument != null) { 165 // add security details 166 addSecurityDetails(holdingAdjustmentDocument, pooledFundValue.getPooledSecurityID(), registrationCode); 167 168 initializeReportLines(holdingAdjustmentDocument.getDocumentNumber(), pooledFundValue.getPooledSecurityID()); 169 170 int counter = 0; 171 // add transaction lines 172 if (taxLots != null) { 173 174 for (HoldingTaxLot holdingTaxLot : taxLots) { 175 176 // check if we reached the maximum number of transaction lines 177 if (counter == maxNumberOfTranLines) { 178 counter = 0; 179 180 // route document 181 validateAndRouteHoldingAdjustmentDocument(holdingAdjustmentDocument, pooledFundValue, isShortTerm); 182 183 // generate a new Holding Adjustment document 184 holdingAdjustmentDocument = generateHoldingAdjustmentDocument(isShortTerm, pooledFundValue.getPooledSecurityID()); 185 186 if (holdingAdjustmentDocument != null) { 187 // add security details 188 addSecurityDetails(holdingAdjustmentDocument, pooledFundValue.getPooledSecurityID(), registrationCode); 189 190 initializeReportLines(holdingAdjustmentDocument.getDocumentNumber(), pooledFundValue.getPooledSecurityID()); 191 } 192 } 193 194 if (holdingAdjustmentDocument != null) { 195 if (addTransactionLine(isShortTerm, holdingAdjustmentDocument, holdingTaxLot, pooledFundValue)) 196 counter++; 197 } 198 199 } 200 } 201 202 if (holdingAdjustmentDocument != null) { 203 // route document 204 validateAndRouteHoldingAdjustmentDocument(holdingAdjustmentDocument, pooledFundValue, isShortTerm); 205 } 206 } 207 } 208 } 209 } 210 211 return result; 212 } 213 214 /** 215 * Groups tax lots by registration code. 216 * 217 * @param holdingTaxLots 218 * @return a map from registration code to taxlots 219 */ 220 protected Map<String, List<HoldingTaxLot>> groupTaxLotsByRegistrationCode(List<HoldingTaxLot> holdingTaxLots) { 221 Map<String, List<HoldingTaxLot>> regCodeMap = new HashMap<String, List<HoldingTaxLot>>(); 222 223 for (HoldingTaxLot holdingTaxLot : holdingTaxLots) { 224 String registrationCode = holdingTaxLot.getRegistrationCode(); 225 if (regCodeMap.containsKey(registrationCode)) { 226 regCodeMap.get(registrationCode).add(holdingTaxLot); 227 } 228 else { 229 List<HoldingTaxLot> tmpTaxLots = new ArrayList<HoldingTaxLot>(); 230 tmpTaxLots.add(holdingTaxLot); 231 regCodeMap.put(registrationCode, tmpTaxLots); 232 } 233 } 234 235 return regCodeMap; 236 } 237 238 239 /** 240 * Generates a HoldingAdjustmentDocument. 241 * 242 * @return the HoldingAdjustmentDocument 243 */ 244 protected HoldingAdjustmentDocument generateHoldingAdjustmentDocument(boolean isShortTerm, String securityId) { 245 HoldingAdjustmentDocument holdingAdjustmentDocument = null; 246 247 String documentDescription = ""; 248 249 if (isShortTerm) { 250 documentDescription = parameterService.getParameterValue(CreateGainLossDistributionTransactionsStep.class, EndowParameterKeyConstants.SHORT_TERM_GAIN_LOSS_DESCRIPTION); 251 } 252 else { 253 documentDescription = parameterService.getParameterValue(CreateGainLossDistributionTransactionsStep.class, EndowParameterKeyConstants.LONG_TERM_GAIN_LOSS_DESCRIPTION); 254 } 255 256 try { 257 holdingAdjustmentDocument = (HoldingAdjustmentDocument) documentService.getNewDocument(getHoldingAdjustmentDocumentTypeName()); 258 holdingAdjustmentDocument.getDocumentHeader().setDocumentDescription(documentDescription); 259 holdingAdjustmentDocument.setTransactionSourceTypeCode(EndowConstants.TransactionSourceTypeCode.AUTOMATED); 260 holdingAdjustmentDocument.setTransactionSubTypeCode(EndowConstants.TransactionSubTypeCode.NON_CASH); 261 } 262 catch (WorkflowException ex) { 263 264 if (isFistTimeForWritingExceptionReport) { 265 if (exceptionReportLine == null) { 266 exceptionReportLine = new TransactionDocumentExceptionReportLine(getHoldingAdjustmentDocumentTypeName(), "", securityId); 267 } 268 gainLossDistributionExceptionReportWriterService.writeTableHeader(exceptionReportLine); 269 isFistTimeForWritingExceptionReport = false; 270 } 271 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 272 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", "WorkflowException while creating a HoldingAdjustmentDocument for Distribution of Gains and Losses Batch process: " + ex.toString()); 273 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 274 } 275 276 return holdingAdjustmentDocument; 277 } 278 279 /** 280 * Creates and add a source security details to the holding adjustment document. 281 * 282 * @param holdingAdjustmentDocument 283 * @param securityId 284 * @param registrationCode 285 */ 286 protected void addSecurityDetails(HoldingAdjustmentDocument holdingAdjustmentDocument, String securityId, String registrationCode) { 287 288 // create new source security details 289 EndowmentSourceTransactionSecurity endowmentSourceTransactionSecurity = new EndowmentSourceTransactionSecurity(); 290 endowmentSourceTransactionSecurity.setDocumentNumber(holdingAdjustmentDocument.getDocumentNumber()); 291 endowmentSourceTransactionSecurity.setSecurityID(securityId); 292 endowmentSourceTransactionSecurity.setRegistrationCode(registrationCode); 293 294 // add it to the document 295 holdingAdjustmentDocument.setSourceTransactionSecurity(endowmentSourceTransactionSecurity); 296 } 297 298 /** 299 * creates a transaction line and setups the data based on isLoss 300 * if isLoss = true then creates source line else creates target line. 301 */ 302 protected EndowmentTransactionLine createEndowmentTransactionLine(boolean isLoss, boolean isShortTerm, HoldingAdjustmentDocument holdingAdjustmentDocument, HoldingTaxLot holdingTaxLot, PooledFundValue pooledFundValue) { 303 EndowmentTransactionLine endowmentTransactionLine = null; 304 305 if (isLoss) { 306 // loss 307 endowmentTransactionLine = new EndowmentSourceTransactionLine(); 308 } 309 else { 310 //gain 311 endowmentTransactionLine = new EndowmentTargetTransactionLine(); 312 } 313 314 if (isShortTerm) { 315 if (isLoss) { 316 endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getShortTermGainLossDistributionPerUnit().negate()); 317 } 318 else { 319 endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getShortTermGainLossDistributionPerUnit()); 320 } 321 } 322 else { 323 if (isLoss) { 324 endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getLongTermGainLossDistributionPerUnit().negate()); 325 } 326 else { 327 endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getLongTermGainLossDistributionPerUnit()); 328 } 329 } 330 331 // populate transaction line 332 endowmentTransactionLine.setDocumentNumber(holdingAdjustmentDocument.getDocumentNumber()); 333 endowmentTransactionLine.setKemid(holdingTaxLot.getKemid()); 334 endowmentTransactionLine.setEtranCode(pooledFundValue.getPooledFundControl().getFundSaleGainLossOffsetTranCode()); 335 endowmentTransactionLine.setTransactionIPIndicatorCode(holdingTaxLot.getIncomePrincipalIndicator()); 336 337 return endowmentTransactionLine; 338 } 339 340 341 /** 342 * Creates and adds a transaction line to the holding adjustment document. 343 * 344 * @param isShortTerm 345 * @param holdingAdjustmentDocument 346 * @param holdingTaxLot 347 * @param gainloss 348 */ 349 protected boolean addTransactionLine(boolean isShortTerm, HoldingAdjustmentDocument holdingAdjustmentDocument, HoldingTaxLot holdingTaxLot, PooledFundValue pooledFundValue) { 350 boolean result = false; 351 boolean isLoss = false; 352 353 if (isShortTerm) { 354 if (pooledFundValue.getShortTermGainLossDistributionPerUnit().signum() == 0) { 355 return false; 356 } 357 if (pooledFundValue.getShortTermGainLossDistributionPerUnit().signum() == -1) { 358 isLoss = true; 359 } 360 } 361 else { 362 if (pooledFundValue.getLongTermGainLossDistributionPerUnit().signum() == 0) { 363 return false; 364 } 365 if (pooledFundValue.getLongTermGainLossDistributionPerUnit().signum() == -1) { 366 isLoss = true; 367 } 368 } 369 370 EndowmentTransactionLine endowmentTransactionLine = createEndowmentTransactionLine(isLoss, isShortTerm, holdingAdjustmentDocument, holdingTaxLot, pooledFundValue); 371 372 if (ObjectUtils.isNull(endowmentTransactionLine)) { 373 exceptionReportLine.setKemid(holdingTaxLot.getKemid()); 374 exceptionReportLine.setSecurityId(pooledFundValue.getPooledSecurityID()); 375 if (isFistTimeForWritingExceptionReport) { 376 gainLossDistributionExceptionReportWriterService.writeTableHeader(exceptionReportLine); 377 isFistTimeForWritingExceptionReport = false; 378 } 379 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 380 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", "Unable to create the transaction line to add to the document."); 381 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 382 383 return false; 384 } 385 386 // if (isShortTerm) { 387 // if (pooledFundValue.getShortTermGainLossDistributionPerUnit().signum() == -1) { 388 // // loss 389 // isLoss = true; 390 // endowmentTransactionLine = new EndowmentSourceTransactionLine(); 391 // endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getShortTermGainLossDistributionPerUnit().negate()); 392 // 393 // } 394 // if (pooledFundValue.getShortTermGainLossDistributionPerUnit().signum() >= 0) { 395 // // gain 396 // isLoss = false; 397 // endowmentTransactionLine = new EndowmentTargetTransactionLine(); 398 // endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getShortTermGainLossDistributionPerUnit()); 399 // } 400 // } 401 // else { 402 // if (pooledFundValue.getLongTermGainLossDistributionPerUnit().signum() == -1) { 403 // // loss 404 // isLoss = true; 405 // endowmentTransactionLine = new EndowmentSourceTransactionLine(); 406 // endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getLongTermGainLossDistributionPerUnit().negate()); 407 // 408 // } 409 // if (pooledFundValue.getLongTermGainLossDistributionPerUnit().signum() >= 0) { 410 // // gain 411 // isLoss = false; 412 // endowmentTransactionLine = new EndowmentTargetTransactionLine(); 413 // endowmentTransactionLine.setUnitAdjustmentAmount(pooledFundValue.getLongTermGainLossDistributionPerUnit()); 414 // } 415 // } 416 417 // // populate transaction line 418 // endowmentTransactionLine.setDocumentNumber(holdingAdjustmentDocument.getDocumentNumber()); 419 // endowmentTransactionLine.setKemid(holdingTaxLot.getKemid()); 420 // endowmentTransactionLine.setEtranCode(pooledFundValue.getPooledFundControl().getFundSaleGainLossOffsetTranCode()); 421 // endowmentTransactionLine.setTransactionIPIndicatorCode(holdingTaxLot.getIncomePrincipalIndicator()); 422 423 // add transaction line 424 String errorPrefix = KFSConstants.EMPTY_STRING; 425 if (endowmentTransactionLine instanceof EndowmentTargetTransactionLine) { 426 errorPrefix = NEW_TARGET_TRAN_LINE_PROPERTY_NAME; 427 } 428 else { 429 errorPrefix = NEW_SOURCE_TRAN_LINE_PROPERTY_NAME; 430 } 431 432 boolean rulesPassed = kualiRuleService.applyRules(new AddTransactionLineEvent(errorPrefix, holdingAdjustmentDocument, endowmentTransactionLine)); 433 434 if (rulesPassed) { 435 if (isLoss) { 436 holdingAdjustmentDocument.addSourceTransactionLine((EndowmentSourceTransactionLine) endowmentTransactionLine); 437 } 438 else { 439 holdingAdjustmentDocument.addTargetTransactionLine((EndowmentTargetTransactionLine) endowmentTransactionLine); 440 } 441 442 // Generate the tax lots for the transaction line 443 updateHoldingAdjustmentDocumentTaxLotsService.updateTransactionLineTaxLotsByUnitAdjustmentAmount(false, holdingAdjustmentDocument, endowmentTransactionLine, isLoss); 444 445 distributionTotalReportLine.addUnitAdjustmentAmount(endowmentTransactionLine.getUnitAdjustmentAmount()); 446 distributionTotalReportLine.addTotalHoldingAdjustmentAmount(endowmentTransactionLine); 447 448 result = true; 449 } 450 else { 451 exceptionReportLine.setKemid(holdingTaxLot.getKemid()); 452 exceptionReportLine.setSecurityId(pooledFundValue.getPooledSecurityID()); 453 if (isFistTimeForWritingExceptionReport) { 454 gainLossDistributionExceptionReportWriterService.writeTableHeader(exceptionReportLine); 455 isFistTimeForWritingExceptionReport = false; 456 } 457 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 458 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 459 for (String errorMessage : errorMessages) { 460 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", errorMessage); 461 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 462 } 463 464 } 465 466 return result; 467 } 468 469 /** 470 * Validates and Routes the HoldingAdjustmentDocument. If document successfully routed set short/long term process complete to 471 * Yes. 472 * 473 * @param holdingAdjustmentDocument 474 * @param pooledFundValue 475 */ 476 protected void validateAndRouteHoldingAdjustmentDocument(HoldingAdjustmentDocument holdingAdjustmentDocument, PooledFundValue pooledFundValue, boolean isShortTerm) { 477 boolean rulesPassed = kualiRuleService.applyRules(new RouteDocumentEvent(holdingAdjustmentDocument)); 478 479 if (rulesPassed) { 480 481 String noRouteIndVal = parameterService.getParameterValue(CreateGainLossDistributionTransactionsStep.class, EndowParameterKeyConstants.GAIN_LOSS_NO_ROUTE_IND); 482 boolean noRouteIndicator = EndowConstants.YES.equalsIgnoreCase(noRouteIndVal) ? true : false; 483 484 try { 485 holdingAdjustmentDocument.setNoRouteIndicator(noRouteIndicator); 486 // TODO figure out if/how we use the ad hoc recipients list 487 documentService.routeDocument(holdingAdjustmentDocument, "Created by Distribution of Gains and Losses Batch process.", null); 488 489 // write a total report line for a HoldingAdjustmentDocument 490 if (isFistTimeForWritingTotalReport) { 491 gainLossDistributionTotalsReportWriterService.writeTableHeader(distributionTotalReportLine); 492 isFistTimeForWritingTotalReport = false; 493 } 494 495 gainLossDistributionTotalsReportWriterService.writeTableRow(distributionTotalReportLine); 496 497 // set short/long term process complete to Yes 498 if (isShortTerm) { 499 pooledFundValue.setShortTermGainLossDistributionComplete(true); 500 } 501 else { 502 pooledFundValue.setLongTermGainLossDistributionComplete(true); 503 } 504 505 // save changes 506 businessObjectService.save(pooledFundValue); 507 } 508 catch (WorkflowException ex) { 509 if (isFistTimeForWritingExceptionReport) { 510 if (exceptionReportLine == null) { 511 exceptionReportLine = new TransactionDocumentExceptionReportLine(getHoldingAdjustmentDocumentTypeName(), "", holdingAdjustmentDocument.getSourceTransactionSecurity().getSecurityID()); 512 } 513 gainLossDistributionExceptionReportWriterService.writeTableHeader(exceptionReportLine); 514 isFistTimeForWritingExceptionReport = false; 515 } 516 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 517 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", "WorkflowException while routing a HoldingAdjustmentDocument for Distribution of Gains and Losses Batch process: " + ex.toString()); 518 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 519 } 520 } 521 else { 522 523 try { 524 // try to save the document 525 documentService.saveDocument(holdingAdjustmentDocument); 526 exceptionReportLine.setSecurityId(holdingAdjustmentDocument.getSourceTransactionSecurity().getSecurityID()); 527 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 528 List<String> errorMessages = GloabalVariablesExtractHelper.extractGlobalVariableErrors(); 529 for (String errorMessage : errorMessages) { 530 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", errorMessage); 531 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 532 } 533 } 534 catch (WorkflowException ex) { 535 // have to write a table header before write the table row. 536 if (isFistTimeForWritingExceptionReport) { 537 gainLossDistributionExceptionReportWriterService.writeTableHeader(exceptionReportLine); 538 isFistTimeForWritingExceptionReport = false; 539 } 540 gainLossDistributionExceptionReportWriterService.writeTableRow(exceptionReportLine); 541 // Write reason as a formatted message in a second line 542 gainLossDistributionExceptionReportWriterService.writeFormattedMessageLine("Reason: %s", "WorkflowException while saving a HoldingAdjustmentDocument for Gain Loss Distribution batch process: " + ex.toString()); 543 gainLossDistributionExceptionReportWriterService.writeNewLines(1); 544 } 545 } 546 } 547 548 549 /** 550 * Gets the HoldingAdjustmentDocument type. 551 * 552 * @return the HoldingAdjustmentDocument type 553 */ 554 protected String getHoldingAdjustmentDocumentTypeName() { 555 return "EHA"; 556 } 557 558 /** 559 * Sets the pooledFundValueService. 560 * 561 * @param pooledFundValueService 562 */ 563 public void setPooledFundValueService(PooledFundValueService pooledFundValueService) { 564 this.pooledFundValueService = pooledFundValueService; 565 } 566 567 /** 568 * Sets the holdingTaxLotService. 569 * 570 * @param holdingTaxLotService 571 */ 572 public void setHoldingTaxLotService(HoldingTaxLotService holdingTaxLotService) { 573 this.holdingTaxLotService = holdingTaxLotService; 574 } 575 576 /** 577 * Sets the parameterService. 578 * 579 * @param parameterService 580 */ 581 public void setParameterService(ParameterService parameterService) { 582 this.parameterService = parameterService; 583 } 584 585 /** 586 * Sets the configService. 587 * 588 * @param configService 589 */ 590 public void setConfigService(KualiConfigurationService configService) { 591 this.configService = configService; 592 } 593 594 /** 595 * Sets the kualiRuleService. 596 * 597 * @param kualiRuleService 598 */ 599 public void setKualiRuleService(KualiRuleService kualiRuleService) { 600 this.kualiRuleService = kualiRuleService; 601 } 602 603 /** 604 * Sets the businessObjectService. 605 * 606 * @param businessObjectService 607 */ 608 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 609 this.businessObjectService = businessObjectService; 610 } 611 612 /** 613 * Sets the documentService. 614 * 615 * @param documentService 616 */ 617 public void setDocumentService(DocumentService documentService) { 618 this.documentService = documentService; 619 } 620 621 /** 622 * Sets the gainLossDistributionExceptionReportWriterService. 623 * 624 * @param gainLossDistributionExceptionReportWriterService 625 */ 626 public void setGainLossDistributionExceptionReportWriterService(ReportWriterService gainLossDistributionExceptionReportWriterService) { 627 this.gainLossDistributionExceptionReportWriterService = gainLossDistributionExceptionReportWriterService; 628 } 629 630 /** 631 * Gets the gainLossDistributionExceptionReportWriterService. 632 * 633 * @return gainLossDistributionExceptionReportWriterService 634 */ 635 public ReportWriterService getGainLossDistributionExceptionReportWriterService() { 636 return gainLossDistributionExceptionReportWriterService; 637 } 638 639 /** 640 * Sets the updateHoldingAdjustmentDocumentTaxLotsService. 641 * 642 * @param updateHoldingAdjustmentDocumentTaxLotsService 643 */ 644 public void setUpdateHoldingAdjustmentDocumentTaxLotsService(UpdateHoldingAdjustmentDocumentTaxLotsService updateHoldingAdjustmentDocumentTaxLotsService) { 645 this.updateHoldingAdjustmentDocumentTaxLotsService = updateHoldingAdjustmentDocumentTaxLotsService; 646 } 647 648 /** 649 * Sets the kemService. 650 * 651 * @param kemService 652 */ 653 public void setKemService(KEMService kemService) { 654 this.kemService = kemService; 655 } 656 657 /** 658 * Initializes the distributionTotalReportLine and exceptionReportLine for further use. 659 * 660 * @param theDocumentId 661 * @param theSecurityId 662 */ 663 protected void initializeReportLines(String theDocumentId, String theSecurityId) { 664 // create a new distributionTotalReportLine for each new HoldingAdjustmentDocument 665 this.distributionTotalReportLine = new GainLossDistributionTotalReportLine(getHoldingAdjustmentDocumentTypeName(), theDocumentId, theSecurityId); 666 667 // create an exceptionReportLine instance that can be reused for reporting multiple errors for a HoldingAdjustmentDocument 668 this.exceptionReportLine = new TransactionDocumentExceptionReportLine(getHoldingAdjustmentDocumentTypeName(), theDocumentId, theSecurityId); 669 670 } 671 672 /** 673 * Gets the gainLossDistributionTotalsReportWriterService. 674 * 675 * @return gainLossDistributionTotalsReportWriterService 676 */ 677 public ReportWriterService getGainLossDistributionTotalsReportWriterService() { 678 return gainLossDistributionTotalsReportWriterService; 679 } 680 681 /** 682 * Sets the gainLossDistributionTotalsReportWriterService. 683 * 684 * @param gainLossDistributionTotalsReportWriterService 685 */ 686 public void setGainLossDistributionTotalsReportWriterService(ReportWriterService gainLossDistributionTotalsReportWriterService) { 687 this.gainLossDistributionTotalsReportWriterService = gainLossDistributionTotalsReportWriterService; 688 } 689 }