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 }