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.document.service.impl;
017
018 import java.math.BigDecimal;
019 import java.util.ArrayList;
020 import java.util.Calendar;
021 import java.util.Collection;
022 import java.util.Date;
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026
027 import org.apache.commons.lang.StringUtils;
028 import org.kuali.kfs.module.endow.EndowConstants;
029 import org.kuali.kfs.module.endow.EndowPropertyConstants;
030 import org.kuali.kfs.module.endow.batch.service.impl.CurrentTaxLotBalanceUpdateServiceImpl;
031 import org.kuali.kfs.module.endow.businessobject.CurrentTaxLotBalance;
032 import org.kuali.kfs.module.endow.businessobject.HoldingHistory;
033 import org.kuali.kfs.module.endow.businessobject.HoldingTaxLot;
034 import org.kuali.kfs.module.endow.businessobject.Security;
035 import org.kuali.kfs.module.endow.dataaccess.CurrentTaxLotBalanceDao;
036 import org.kuali.kfs.module.endow.dataaccess.TransactionArchiveDao;
037 import org.kuali.kfs.module.endow.document.service.CurrentTaxLotService;
038 import org.kuali.kfs.module.endow.document.service.KEMService;
039 import org.kuali.kfs.module.endow.document.service.SecurityService;
040 import org.kuali.kfs.module.endow.util.KEMCalculationRoundingHelper;
041 import org.kuali.kfs.sys.context.SpringContext;
042 import org.kuali.rice.kns.service.BusinessObjectService;
043 import org.kuali.rice.kns.service.DataDictionaryService;
044 import org.kuali.rice.kns.util.KualiInteger;
045 import org.kuali.rice.kns.util.ObjectUtils;
046 import org.springframework.transaction.annotation.Transactional;
047
048 /**
049 * Implementation to provide services for CurrentTaxLotBalance business object.
050 */
051 @Transactional
052 public class CurrentTaxLotServiceImpl implements CurrentTaxLotService {
053 protected BusinessObjectService businessObjectService;
054 protected SecurityService securityService;
055 protected KEMService kEMService;
056 protected CurrentTaxLotBalanceDao currentTaxLotBalanceDao;
057 protected TransactionArchiveDao transactionArchiveDao;
058
059 /**
060 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getByPrimaryKey(java.lang.String, java.lang.String,
061 * java.lang.String, int, java.lang.String)
062 */
063 public CurrentTaxLotBalance getByPrimaryKey(String kemid, String securityId, String registrationCode, KualiInteger lotNumber, String ipIndicator) {
064 Map<String, String> primaryKeys = new HashMap<String, String>();
065
066 primaryKeys.put(EndowPropertyConstants.CURRENT_TAX_LOT_KEMID, kemid);
067 primaryKeys.put(EndowPropertyConstants.CURRENT_TAX_LOT_SECURITY_ID, securityId);
068 primaryKeys.put(EndowPropertyConstants.CURRENT_TAX_LOT_REGIS_CD, registrationCode);
069 primaryKeys.put(EndowPropertyConstants.CURRENT_TAX_LOT_LOT_NBR, String.valueOf(lotNumber));
070 primaryKeys.put(EndowPropertyConstants.CURRENT_TAX_LOT_IP_IND, ipIndicator);
071
072 return (CurrentTaxLotBalance) businessObjectService.findByPrimaryKey(CurrentTaxLotBalance.class, primaryKeys);
073
074 }
075
076 /**
077 * @org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalancesForMatchingSecurityClassCode(String)
078 */
079 public Collection<CurrentTaxLotBalance>getCurrentTaxLotBalancesForMatchingSecurityClassCode(String securityClassCode) {
080 Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList();
081
082 Collection<Security> securities = new ArrayList();
083
084 if (StringUtils.isNotBlank(securityClassCode)) {
085 Map criteria = new HashMap();
086
087 if (SpringContext.getBean(DataDictionaryService.class).getAttributeForceUppercase(Security.class, EndowPropertyConstants.SECURITY_CLASS_CODE)) {
088 securityClassCode = securityClassCode.toUpperCase();
089 }
090 criteria.put(EndowPropertyConstants.SECURITY_CLASS_CODE, securityClassCode);
091
092 securities = businessObjectService.findMatching(Security.class, criteria);
093
094 for (Security security : securities) {
095 criteria.clear();
096 criteria.put(EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_SECURITY_ID, security.getId());
097
098 currentTaxLotBalances.addAll(businessObjectService.findMatching(HoldingHistory.class, criteria));
099 }
100 }
101
102 return currentTaxLotBalances;
103 }
104
105 /**
106 * @org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalancesForMatchingSecurityClassCodeAndSecurityId(String, String)
107 */
108 public Collection<CurrentTaxLotBalance>getCurrentTaxLotBalancesForMatchingSecurityClassCodeAndSecurityId(String securityClassCode, String securityId) {
109 Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList();
110
111 currentTaxLotBalances = getCurrentTaxLotBalancesForMatchingSecurityClassCode(securityClassCode);
112 currentTaxLotBalances.addAll(getCurrentTaxLotBalancesBySecurityId(securityId));
113
114 return currentTaxLotBalances;
115 }
116
117
118 /**
119 * @org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalancesBySecurityId(String)
120 */
121 public Collection<CurrentTaxLotBalance>getCurrentTaxLotBalancesBySecurityId(String securityId) {
122 Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList();
123
124 if (StringUtils.isNotBlank(securityId)) {
125 Map criteria = new HashMap();
126
127 if (SpringContext.getBean(DataDictionaryService.class).getAttributeForceUppercase(CurrentTaxLotBalance.class, EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_SECURITY_ID)) {
128 securityId = securityId.toUpperCase();
129 }
130
131 criteria.put(EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_SECURITY_ID, securityId);
132
133 currentTaxLotBalances = businessObjectService.findMatching(CurrentTaxLotBalance.class, criteria);
134 }
135
136 return currentTaxLotBalances;
137 }
138
139 /**
140 * @org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalancesBySecurityId(String)
141 */
142 public Collection<CurrentTaxLotBalance>getCurrentTaxLotBalancesByIncomePrincipalIndicator(String incomePrincipalIndicator) {
143 Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList();
144
145 if (StringUtils.isNotBlank(incomePrincipalIndicator)) {
146 Map criteria = new HashMap();
147
148 if (SpringContext.getBean(DataDictionaryService.class).getAttributeForceUppercase(CurrentTaxLotBalance.class, EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_INCOME_PRINCIPAL_INDICATOR)) {
149 incomePrincipalIndicator = incomePrincipalIndicator.toUpperCase();
150 }
151
152 criteria.put(EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_INCOME_PRINCIPAL_INDICATOR, incomePrincipalIndicator);
153
154 currentTaxLotBalances = businessObjectService.findMatching(CurrentTaxLotBalance.class, criteria);
155 }
156
157 return currentTaxLotBalances;
158 }
159
160 /**
161 * @org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getAllCurrentTaxLotBalance()
162 */
163 public Collection<CurrentTaxLotBalance> getAllCurrentTaxLotBalance() {
164 Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList();
165
166 currentTaxLotBalances = businessObjectService.findAll(CurrentTaxLotBalance.class);
167
168 return currentTaxLotBalances;
169 }
170
171 /**
172 * Service Method to create a new current tax lot balance record and copy HoldingTaxLot record to it
173 *
174 * @param holdingTaxLot
175 * @return currentTaxLotBalance
176 */
177 public CurrentTaxLotBalance copyHoldingTaxLotToCurrentTaxLotBalance(HoldingTaxLot holdingTaxLot) {
178 CurrentTaxLotBalance currentTaxLotBalance = new CurrentTaxLotBalance();
179
180 currentTaxLotBalance.setKemid(holdingTaxLot.getKemid());
181 currentTaxLotBalance.setSecurityId(holdingTaxLot.getSecurityId());
182 currentTaxLotBalance.setRegistrationCode(holdingTaxLot.getRegistrationCode());
183 currentTaxLotBalance.setLotNumber(holdingTaxLot.getLotNumber());
184 currentTaxLotBalance.setIncomePrincipalIndicator(holdingTaxLot.getIncomePrincipalIndicator());
185
186 currentTaxLotBalance.setUnits(holdingTaxLot.getUnits());
187 currentTaxLotBalance.setCost(holdingTaxLot.getCost());
188 currentTaxLotBalance.setAcquiredDate(holdingTaxLot.getAcquiredDate());
189 currentTaxLotBalance.setPriorAccrual(holdingTaxLot.getPriorAccrual());
190 currentTaxLotBalance.setCurrentAccrual(holdingTaxLot.getCurrentAccrual());
191 currentTaxLotBalance.setLastTransactionDate(holdingTaxLot.getLastTransactionDate());
192
193 return currentTaxLotBalance;
194 }
195
196 /**
197 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getByPrimaryKey(java.lang.String, java.lang.String,
198 * java.lang.String, int, java.lang.String)
199 */
200 public void updateCurrentTaxLotBalance(CurrentTaxLotBalance currentTaxLotBalance) {
201 if (currentTaxLotBalance == null) {
202 throw new IllegalArgumentException("invalid (null) currentTaxLotBalance");
203 }
204
205 businessObjectService.save(currentTaxLotBalance);
206 }
207
208 /**
209 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#clearAllCurrentTaxLotRecords() clears all the records
210 * from the CurrentTaxLotBalance table.
211 */
212 public void clearAllCurrentTaxLotRecords() {
213 Collection<CurrentTaxLotBalance> currentTaxLotBalances = businessObjectService.findAll(CurrentTaxLotBalance.class);
214
215 for (CurrentTaxLotBalance currentTaxLotBalance : currentTaxLotBalances) {
216 businessObjectService.delete(currentTaxLotBalance);
217 }
218 }
219
220 /**
221 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalanceSecurityUnitValue(String) Method
222 * to get the security unit value for the current balance tax lot record
223 * @param securityId
224 * @return securityUnitValue
225 */
226 public BigDecimal getCurrentTaxLotBalanceSecurityUnitValue(String securityId) {
227 BigDecimal securityUnitValue = BigDecimal.ZERO;
228
229 Security security = securityService.getByPrimaryKey(securityId);
230
231 return security.getUnitValue();
232 }
233
234 /**
235 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getNextTwelveMonthsEstimatedValue(String) Method to
236 * calculate Next Twelve Months Estimated value
237 * @param securityId
238 * @return nextTwelveMonthsEstimatedValue
239 */
240 public BigDecimal getNextTwelveMonthsEstimatedValue(HoldingTaxLot holdingTaxLot, String securityId) {
241 BigDecimal nextTweleveMonthsEstimatedValue = BigDecimal.ZERO;
242
243 Security security = securityService.getByPrimaryKey(securityId);
244
245 return KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
246 }
247
248 /**
249 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getRemainderOfFiscalYearEstimatedIncome(HoldingTaxLot,
250 * String) Method to calculate remainder of fiscal year estimated income
251 * @param securityId
252 * @return remainderOfFiscalYearEstimatedIncome
253 */
254 public BigDecimal getRemainderOfFiscalYearEstimatedIncome(HoldingTaxLot holdingTaxLot, String securityId) {
255 BigDecimal incomeAmount = BigDecimal.ZERO;
256
257 Security security = securityService.getByPrimaryKey(securityId);
258
259 String classCodeType = security.getClassCode().getClassCodeType();
260
261 if (EndowConstants.ClassCodeTypes.ALTERNATIVE_INVESTMENT.equalsIgnoreCase(classCodeType)) {
262 return BigDecimal.ZERO;
263 }
264 // calculations for BONDS
265 if (EndowConstants.ClassCodeTypes.BOND.equalsIgnoreCase(classCodeType)) {
266 return getRemainderOfFiscalYearEstimatedIncomeForBonds(security, holdingTaxLot);
267 }
268
269 // calculations for CASH
270 if (EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS.equalsIgnoreCase(classCodeType)) {
271 return getRemainderOfFiscalYearEstimatedIncomeForCash(security, holdingTaxLot);
272 }
273
274 // calculations for LIABILITIES
275 if (EndowConstants.ClassCodeTypes.LIABILITY.equalsIgnoreCase(classCodeType)) {
276 return BigDecimal.ZERO;
277 }
278
279 // calculations for OTHER
280 if (EndowConstants.ClassCodeTypes.OTHER.equalsIgnoreCase(classCodeType)) {
281 return BigDecimal.ZERO;
282 }
283
284 // calculations for POOLED FUNDS
285 if (EndowConstants.ClassCodeTypes.POOLED_INVESTMENT.equalsIgnoreCase(classCodeType)) {
286 return getRemainderOfFiscalYearEstimatedIncomeForPooledFunds(security, holdingTaxLot);
287 }
288
289 // calculations for STOCKS
290 if (EndowConstants.ClassCodeTypes.STOCKS.equalsIgnoreCase(classCodeType)) {
291 return getRemainderOfFiscalYearEstimatedIncomeForStocks(security, holdingTaxLot);
292 }
293
294 return incomeAmount;
295
296 }
297
298 /**
299 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getNextFiscalYearInvestmentIncome(HoldingTaxLot,
300 * String) Method to calculate next fiscal year investment income
301 * @param securityId
302 * @return nextFiscalyearInvestmentIncome
303 */
304 public BigDecimal getNextFiscalYearInvestmentIncome(HoldingTaxLot holdingTaxLot, String securityId) {
305 BigDecimal nextFiscalyearInvestmentIncome = BigDecimal.ZERO;
306
307 Security security = securityService.getByPrimaryKey(securityId);
308 nextFiscalyearInvestmentIncome = KEMCalculationRoundingHelper.multiply(security.getNextFiscalYearDistributionAmount(), holdingTaxLot.getUnits(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
309
310 return nextFiscalyearInvestmentIncome;
311 }
312
313 /**
314 * calculates the remainder of fiscal year estimated income for bonds
315 *
316 * @param security
317 * @param holdingTaxLot
318 * @return amount
319 */
320 protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForBonds(Security security, HoldingTaxLot holdingTaxLot) {
321 BigDecimal amount = BigDecimal.ZERO;
322
323 if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) {
324 return amount;
325 }
326
327 Date nextIncomeDueDate = security.getIncomeNextPayDate();
328 if (ObjectUtils.isNull(nextIncomeDueDate)) {
329 return amount;
330 }
331
332 Date fiscalYearEndDate = getFiscalYearEndDate();
333
334 // BONDS - rule 2.a
335 if (nextIncomeDueDate.after(fiscalYearEndDate)) {
336 return BigDecimal.ZERO;
337 }
338
339 int numberOfMonthsRemaining = getNumberOfMonthsRemaining(fiscalYearEndDate, nextIncomeDueDate);
340 // rule 2.b
341 if (nextIncomeDueDate.before(fiscalYearEndDate) && numberOfMonthsRemaining < EndowConstants.NUMBER_OF_MONTHS_REMAINING) {
342 amount = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
343 amount = KEMCalculationRoundingHelper.divide(amount, BigDecimal.valueOf(2), EndowConstants.Scale.SECURITY_MARKET_VALUE);
344 }
345 else {
346 amount = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
347 }
348
349 return amount;
350 }
351
352 /**
353 * Helper method to calculate the number of months
354 *
355 * @param fiscalYearEndDate
356 * @param nextIncomeDueDate
357 * @return numberOfMonths
358 */
359 protected int getNumberOfMonthsRemaining(Date fiscalYearEndDate, Date nextIncomeDueDate) {
360 int numberOfMonths = 0;
361
362 Calendar calendar = Calendar.getInstance();
363
364 calendar.setTime(fiscalYearEndDate);
365 int fiscalMonths = calendar.get(Calendar.MONTH) + 1;
366 int fiscalYear = calendar.get(Calendar.YEAR);
367
368 calendar.setTime(nextIncomeDueDate);
369 int nextIncomeMonths = calendar.get(Calendar.MONTH) + 1;
370 int nextIncomeYear = calendar.get(Calendar.YEAR);
371
372 numberOfMonths = ((fiscalYear-nextIncomeYear) * 12);
373 numberOfMonths += fiscalMonths - nextIncomeMonths;
374
375 return numberOfMonths;
376 }
377
378 /**
379 * Helper method to get the system parameter FISCAL_YEAR_END_DAY_AND_MONTH and convert the value into a date value
380 */
381 protected Date getFiscalYearEndDate() {
382 Date fiscalYearEndDate = null;
383
384 fiscalYearEndDate = kEMService.getFiscalYearEndDayAndMonth();
385
386 if (fiscalYearEndDate == null) {
387 throw new RuntimeException("ParseException: CurrentTaxLotBalanceUpdateStep job stopped because System Parameter FISCAL_YEAR_END_DAY_AND_MONTH is invalid");
388 }
389
390 return fiscalYearEndDate;
391 }
392
393 /**
394 * calculates the remainder of fiscal year estimated income for cash
395 *
396 * @param security
397 * @param holdingTaxLot
398 * @return amount
399 */
400 protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForCash(Security security, HoldingTaxLot holdingTaxLot) {
401 BigDecimal amount = BigDecimal.ZERO;
402
403 if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) {
404 return amount;
405 }
406
407 Date nextIncomeDueDate = security.getIncomeNextPayDate();
408 Date fiscalYearEndDate = getFiscalYearEndDate();
409 String incomePayFrequency = security.getIncomePayFrequency();
410
411 if (ObjectUtils.isNull(nextIncomeDueDate) || ObjectUtils.isNull(incomePayFrequency)) {
412 return amount;
413 }
414
415 // BONDS - rule 3.a
416 if (nextIncomeDueDate.after(fiscalYearEndDate)) {
417 return BigDecimal.ZERO;
418 }
419
420 // rule 3.b
421 if (nextIncomeDueDate.before(fiscalYearEndDate)) {
422 Date lastPaymentDate = getLastPaymentDate(incomePayFrequency, fiscalYearEndDate);
423 long daysToLastPayment = getTotalDaysToLastPayment(lastPaymentDate, nextIncomeDueDate);
424
425 amount = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
426 amount = amount.multiply(BigDecimal.valueOf(daysToLastPayment));
427 amount = KEMCalculationRoundingHelper.divide(amount, BigDecimal.valueOf(EndowConstants.NUMBER_OF_DAYS_IN_YEAR), EndowConstants.Scale.SECURITY_MARKET_VALUE);
428 amount = amount.add(holdingTaxLot.getCurrentAccrual());
429 }
430
431 return amount;
432 }
433
434 /**
435 * Helper method to calculate the number of days to the last payment
436 */
437 protected long getTotalDaysToLastPayment(Date lastPaymentDate, Date nextIncomeDueDate) {
438 long totalDays = 0;
439 long MILLISECS_PER_DAY = (1000*60*60*24) ; // total milliseconds in a day
440
441 Calendar currentDateCalendar = Calendar.getInstance();
442 currentDateCalendar.setTime(kEMService.getCurrentDate());
443 currentDateCalendar.set(Calendar.HOUR, 0);
444 currentDateCalendar.set(Calendar.MINUTE, 0);
445 currentDateCalendar.set(Calendar.SECOND, 0);
446
447 Calendar lastPaymentDateCalendar = Calendar.getInstance();
448 lastPaymentDateCalendar.setTime(lastPaymentDate);
449 lastPaymentDateCalendar.set(Calendar.HOUR, 0);
450 lastPaymentDateCalendar.set(Calendar.MINUTE, 0);
451 lastPaymentDateCalendar.set(Calendar.SECOND, 0);
452
453 //to take care of leap year and day light savings time.
454 long endL = lastPaymentDateCalendar.getTimeInMillis() + lastPaymentDateCalendar.getTimeZone().getOffset(lastPaymentDateCalendar.getTimeInMillis());
455 long startL = currentDateCalendar.getTimeInMillis() + currentDateCalendar.getTimeZone().getOffset(currentDateCalendar.getTimeInMillis());
456
457 return (endL - startL) / MILLISECS_PER_DAY ;
458 }
459
460 /**
461 * Helper method to examine the SEC_INC_PAY_FREQ and determine the date of the last payment to be made in the fiscal year.
462 */
463 protected Date getLastPaymentDate(String incomePayFrequency, Date fiscalYearEndDate) {
464 Date lastPaymentDate = null;
465
466 String frequencyType = incomePayFrequency.substring(0, 1);
467
468 Date currentDate = kEMService.getCurrentDate();
469
470 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.DAILY)) {
471 return fiscalYearEndDate;
472 }
473
474 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.WEEKLY)) {
475 return calculateLastPaymentWeekDate(currentDate, fiscalYearEndDate);
476 }
477
478 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_MONTHLY)) {
479 String dayOfSemiMonthly = incomePayFrequency.substring(1, 3);
480 return calculateLastPaymentSemiMonthlyDate(currentDate, fiscalYearEndDate, dayOfSemiMonthly);
481 }
482
483 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.MONTHLY)) {
484 String dayOfMonth = incomePayFrequency.substring(1, 3);
485 return calculateLastPaymentMonthlyDate(currentDate, fiscalYearEndDate, dayOfMonth);
486 }
487
488 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.QUARTERLY)) {
489 String month = incomePayFrequency.substring(1, 2);
490 String dayOfMonth = incomePayFrequency.substring(2, 4);
491
492 return calculateLastPaymentQuarterlyDate(currentDate, fiscalYearEndDate, dayOfMonth, month);
493 }
494
495 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_ANNUALLY)) {
496 String month = incomePayFrequency.substring(1, 2);
497 String dayOfMonth = incomePayFrequency.substring(2, 4);
498
499 return calculateLastPaymentSemiAnnuallyDate(currentDate, fiscalYearEndDate, dayOfMonth, month);
500 }
501
502 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.ANNUALLY)) {
503 String month = incomePayFrequency.substring(1, 2);
504 String dayOfMonth = incomePayFrequency.substring(2, 4);
505
506 return calculateLastPaymentAnnuallyDate(currentDate, fiscalYearEndDate, dayOfMonth, month);
507 }
508
509 return lastPaymentDate;
510 }
511
512 /**
513 * Method to calculate the last payment date for WEEKLY frequency code
514 * @param currentDate, fiscalYearEndDate
515 * @return lastPaymentDate
516 */
517 protected Date calculateLastPaymentWeekDate(Date currentDate, Date fiscalYearEndDate) {
518 Calendar calendar = Calendar.getInstance();
519 calendar.setTime(currentDate);
520
521 while (calendar.getTime().before(fiscalYearEndDate)) {
522 calendar.add(Calendar.DAY_OF_MONTH, 7);
523 }
524
525 if (calendar.getTime().after(fiscalYearEndDate)) {
526 calendar.add(Calendar.DAY_OF_MONTH, -7);
527 }
528
529 return new java.sql.Date(calendar.getTimeInMillis());
530 }
531
532 /**
533 * Method to calculate the last payment date for semimonthly frequency code
534 * @param currentDate, fiscalYearEndDate, dayOfSemiMonthly
535 * @return lastPaymentDate
536 */
537 protected Date calculateLastPaymentSemiMonthlyDate(Date currentDate, Date fiscalYearEndDate, String dayOfSemiMonthly) {
538 Calendar calendar = Calendar.getInstance();
539 calendar.setTime(currentDate);
540
541 int dayOfMonthToSet = Integer.parseInt(dayOfSemiMonthly);
542 calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthToSet);
543
544 while (calendar.getTime().before(fiscalYearEndDate)) {
545 calendar.add(Calendar.DAY_OF_MONTH, 15);
546 }
547
548 if (calendar.getTime().after(fiscalYearEndDate)) {
549 calendar.add(Calendar.DAY_OF_MONTH, -15);
550 }
551
552 return new java.sql.Date(calendar.getTimeInMillis());
553 }
554
555 /**
556 * Method to calculate the last payment date for semimonthly frequency code
557 * @param currentDate, fiscalYearEndDate, dayOfMonth
558 * @return lastPaymentDate
559 */
560 protected Date calculateLastPaymentMonthlyDate(Date currentDate, Date fiscalYearEndDate, String dayOfMonth) {
561 Calendar calendar = Calendar.getInstance();
562 calendar.setTime(currentDate);
563
564 int dayOfMonthToSet = Integer.parseInt(dayOfMonth);
565 calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthToSet);
566
567 while (calendar.getTime().before(fiscalYearEndDate)) {
568 calendar.add(Calendar.MONTH, 1);
569 }
570
571 if (calendar.getTime().after(fiscalYearEndDate)) {
572 calendar.add(Calendar.MONTH, -1);
573 }
574
575 return new java.sql.Date(calendar.getTimeInMillis());
576 }
577
578 /**
579 * Method to calculate the last payment date for quarterly frequency code
580 * @param currentDate, fiscalYearEndDate, dayOfMonth
581 * @return lastPaymentDate
582 */
583 protected Date calculateLastPaymentQuarterlyDate(Date currentDate, Date fiscalYearEndDate, String dayOfMonth, String month) {
584 Calendar calendar = setCaledarWithMonth(month, currentDate);
585 setCalendarWithDays(calendar, dayOfMonth);
586
587 while (calendar.getTime().before(fiscalYearEndDate)) {
588 calendar.add(Calendar.MONTH, 3);
589 }
590
591 if (calendar.getTime().after(fiscalYearEndDate)) {
592 calendar.add(Calendar.MONTH, -3);
593 }
594
595 return new java.sql.Date(calendar.getTimeInMillis());
596 }
597
598 /**
599 * Method to calculate the last payment date for SemiAnnually frequency code
600 * @param currentDate, fiscalYearEndDate, dayOfMonth
601 * @return lastPaymentDate
602 */
603 protected Date calculateLastPaymentSemiAnnuallyDate(Date currentDate, Date fiscalYearEndDate, String dayOfMonth, String month) {
604 Calendar calendar = setCaledarWithMonth(month, currentDate);
605 setCalendarWithDays(calendar, dayOfMonth);
606
607 while (calendar.getTime().before(fiscalYearEndDate)) {
608 calendar.add(Calendar.MONTH, 6);
609 }
610
611 if (calendar.getTime().after(fiscalYearEndDate)) {
612 calendar.add(Calendar.MONTH, -6);
613 }
614
615 return new java.sql.Date(calendar.getTimeInMillis());
616 }
617
618 /**
619 * Method to calculate the last payment date for Annually frequency code
620 * @param currentDate, fiscalYearEndDate, dayOfMonth
621 * @return lastPaymentDate
622 */
623 protected Date calculateLastPaymentAnnuallyDate(Date currentDate, Date fiscalYearEndDate, String dayOfMonth, String month) {
624 Calendar calendar = setCaledarWithMonth(month, currentDate);
625 setCalendarWithDays(calendar, dayOfMonth);
626
627 while (calendar.getTime().before(fiscalYearEndDate)) {
628 calendar.add(Calendar.YEAR, 1);
629 }
630
631 if (calendar.getTime().after(fiscalYearEndDate)) {
632 calendar.add(Calendar.YEAR, -1);
633 }
634
635 return new java.sql.Date(calendar.getTimeInMillis());
636 }
637
638 /**
639 * This method will check the current month and set the calendar to that month
640 * @param month month to set the calendar, currentDate currentDate
641 * @return calendar calendar is set to the month selected
642 */
643 protected Calendar setCaledarWithMonth(String month, Date lastPaymentDate) {
644 Calendar calendar = Calendar.getInstance();
645 calendar.setTime(lastPaymentDate);
646
647 int calendarMonth = 1;
648
649 if (EndowConstants.FrequencyMonths.JANUARY.equalsIgnoreCase(month)) {
650 calendarMonth = Calendar.JANUARY;
651 } else if (EndowConstants.FrequencyMonths.FEBRUARY.equalsIgnoreCase(month)) {
652 calendarMonth = Calendar.FEBRUARY;
653 } else if (EndowConstants.FrequencyMonths.MARCH.equalsIgnoreCase(month)) {
654 calendarMonth = Calendar.MARCH;
655 } else if (EndowConstants.FrequencyMonths.APRIL.equalsIgnoreCase(month)) {
656 calendarMonth = Calendar.APRIL;
657 } else if (EndowConstants.FrequencyMonths.MAY.equalsIgnoreCase(month)) {
658 calendarMonth = Calendar.MAY;
659 } else if (EndowConstants.FrequencyMonths.JUNE.equalsIgnoreCase(month)) {
660 calendarMonth = Calendar.JUNE;
661 } else if (EndowConstants.FrequencyMonths.JULY.equalsIgnoreCase(month)) {
662 calendarMonth = Calendar.JULY;
663 } else if (EndowConstants.FrequencyMonths.AUGUST.equalsIgnoreCase(month)) {
664 calendarMonth = Calendar.AUGUST;
665 } else if (EndowConstants.FrequencyMonths.SEPTEMBER.equalsIgnoreCase(month)) {
666 calendarMonth = Calendar.SEPTEMBER;
667 } else if (EndowConstants.FrequencyMonths.OCTOBER.equalsIgnoreCase(month)) {
668 calendarMonth = Calendar.OCTOBER;
669 } else if (EndowConstants.FrequencyMonths.NOVEMBER.equalsIgnoreCase(month)) {
670 calendarMonth = Calendar.NOVEMBER;
671 } else if (EndowConstants.FrequencyMonths.DECEMBER.equalsIgnoreCase(month)) {
672 calendarMonth = Calendar.DECEMBER;
673 }
674
675 calendar.set(Calendar.MONTH, calendarMonth);
676
677 return calendar;
678 }
679
680 /**
681 * This method will check the current month and set the calendar to that month
682 * @param month, dayOfMonth month to set the calendar, dayOfMonth day of the month to set to
683 * @return calendar calendar is set to the month selected
684 */
685 protected void setCalendarWithDays(Calendar calendar, String dayOfMonth) {
686 int dayInMonthToSet;
687 int calendarMonth = calendar.get(Calendar.MONTH);
688
689 if (StringUtils.equalsIgnoreCase(dayOfMonth, EndowConstants.FrequencyMonthly.MONTH_END)) { // month end for the month so need to get max days...
690 dayInMonthToSet = checkMaximumDaysInMonth(calendar.get(Calendar.MONTH));
691 } else {
692 dayInMonthToSet = Integer.parseInt(dayOfMonth);
693
694 if (dayInMonthToSet > 29 && calendarMonth == Calendar.FEBRUARY) {
695 dayInMonthToSet = checkMaximumDaysInFebruary();
696 } else if (dayInMonthToSet > 30 && (calendarMonth == Calendar.APRIL || calendarMonth == Calendar.JUNE ||
697 calendarMonth == Calendar.SEPTEMBER || calendarMonth == Calendar.NOVEMBER)) {
698 dayInMonthToSet = 30;
699 dayInMonthToSet = checkMaximumDaysInMonth(calendarMonth);
700 }
701 }
702
703 calendar.set(Calendar.DAY_OF_MONTH, dayInMonthToSet);
704 }
705
706 /**
707 * This method will check and return either maximum days in the month as 28 or 29 for leap year.
708 * It first sets the month to February and then checks the maximum days..
709 * @return maxDays Maximum number of days in the month of February for calendar.
710 */
711 protected int checkMaximumDaysInFebruary() {
712 int maxDays;
713 Calendar februaryMonthlyDateCalendar = Calendar.getInstance();
714 februaryMonthlyDateCalendar.set(Calendar.MONTH, Calendar.FEBRUARY);
715 maxDays = februaryMonthlyDateCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
716
717 return maxDays;
718 }
719
720 /**
721 * This method will check and return maximum days in a month.
722 * @param monthNumber The number of the month to test for maximum days..
723 * @return maxDays Maximum number of days in the month of February for calendar.
724 */
725 protected int checkMaximumDaysInMonth(int monthNumber) {
726 int maxDays;
727
728 Calendar calendar = Calendar.getInstance();
729 calendar.set(Calendar.MONTH, monthNumber);
730 maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
731
732 return maxDays;
733 }
734
735 /**
736 * calculates the remainder of fiscal year estimated income for pooled funds
737 *
738 * @param security
739 * @param holdingTaxLot
740 * @return amount
741 */
742 protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForPooledFunds(Security security, HoldingTaxLot holdingTaxLot) {
743 BigDecimal amount = BigDecimal.ZERO;
744
745 if (ObjectUtils.isNull(security.getIncomeNextPayDate()) || ObjectUtils.isNull(security.getFrequencyCode())) {
746 return amount;
747 }
748
749 Date nextIncomeDueDate = security.getIncomeNextPayDate();
750 if (ObjectUtils.isNull(nextIncomeDueDate)) {
751 return amount;
752 }
753
754 Date fiscalYearEndDate = getFiscalYearEndDate();
755
756 // BONDS - rule 4.a
757 if (nextIncomeDueDate.after(fiscalYearEndDate)) {
758 return BigDecimal.ZERO;
759 }
760
761 // rule 4.b
762 if (nextIncomeDueDate.before(fiscalYearEndDate)) {
763 String incomePayFrequency = security.getIncomePayFrequency();
764 if (ObjectUtils.isNull(incomePayFrequency)) {
765 return amount;
766 }
767
768 Date lastPaymentDate = getLastPaymentDate(incomePayFrequency, fiscalYearEndDate);
769
770 long paymentsRemaining = getTotalPaymentsRemaining(lastPaymentDate, fiscalYearEndDate, incomePayFrequency, nextIncomeDueDate);
771
772 long totalNumberOfPayments = kEMService.getTotalNumberOfPaymentsForFiscalYear();
773
774 amount = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
775 amount = amount.multiply(BigDecimal.valueOf(paymentsRemaining));
776 amount = KEMCalculationRoundingHelper.divide(amount, BigDecimal.valueOf(totalNumberOfPayments), EndowConstants.Scale.SECURITY_MARKET_VALUE);
777 amount = amount.add(holdingTaxLot.getCurrentAccrual());
778 }
779
780 return amount;
781 }
782
783 /**
784 * Helper method to calculate the remaining payments till the last payment date for the fiscal year
785 * @param lastPaymentDate, fiscalYearEndDate, incomePayFrequency
786 * @return totalPaymentsRemaining
787 */
788 protected long getTotalPaymentsRemaining(Date lastPaymentDate, Date fiscalYearEndDate, String incomePayFrequency, Date nextIncomeDueDate) {
789 long totalPaymentsRemaining = 0;
790 long totalDaysToLastPayment = getTotalDaysToLastPayment(lastPaymentDate, nextIncomeDueDate);
791
792 String frequencyType = incomePayFrequency.substring(0, 1);
793
794 Date currentDate = kEMService.getCurrentDate();
795
796 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.DAILY)) {
797 return totalDaysToLastPayment;
798 }
799
800 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.WEEKLY)) {
801 return (totalDaysToLastPayment / 7);
802 }
803
804 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_MONTHLY)) {
805 return (totalDaysToLastPayment / 15);
806 }
807
808 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.MONTHLY)) {
809 String dayOfMonth = incomePayFrequency.substring(1, 3);
810 return getNumberOfPaymentsRemainingForMonthlyFrequency(nextIncomeDueDate, lastPaymentDate, dayOfMonth);
811 }
812
813 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.QUARTERLY)) {
814 String month = incomePayFrequency.substring(1, 2);
815 String dayOfMonth = incomePayFrequency.substring(2, 4);
816
817 return getNumberOfPaymentsRemainingForQuarterlyFrequency(nextIncomeDueDate, lastPaymentDate, dayOfMonth, month);
818 }
819
820 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.SEMI_ANNUALLY)) {
821 String month = incomePayFrequency.substring(1, 2);
822 String dayOfMonth = incomePayFrequency.substring(2, 4);
823
824 return getNumberOfPaymentsRemainingForSemiAnnuallyDate(nextIncomeDueDate, lastPaymentDate, dayOfMonth, month);
825 }
826
827 if (frequencyType.equalsIgnoreCase(EndowConstants.FrequencyTypes.ANNUALLY)) {
828 String month = incomePayFrequency.substring(1, 2);
829 String dayOfMonth = incomePayFrequency.substring(2, 4);
830
831 return getNumberOfPaymentsRemainingForAnnuallyDate(nextIncomeDueDate, lastPaymentDate, dayOfMonth, month);
832 }
833
834 return totalPaymentsRemaining;
835 }
836
837 /**
838 * Method to calculate the last payment date for monthly frequency code
839 * @param currentDate, fiscalYearEndDate, dayOfMonth
840 * @return totalPayments
841 */
842 protected long getNumberOfPaymentsRemainingForMonthlyFrequency(Date nextIncomeDueDate, Date lastPaymentDate, String dayOfMonth) {
843 long totalPayments = 0;
844
845 Calendar calendar = Calendar.getInstance();
846 calendar.setTime(nextIncomeDueDate);
847
848 int dayOfMonthToSet = Integer.parseInt(dayOfMonth);
849 calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthToSet);
850
851 if (calendar.getTime().before(lastPaymentDate)) {
852 totalPayments = totalPayments + 1;
853 }
854 else {
855 return totalPayments;
856 }
857
858 while (calendar.getTime().before(lastPaymentDate)) {
859 calendar.add(Calendar.MONTH, 1);
860 totalPayments = totalPayments + 1;
861 }
862
863 return totalPayments;
864 }
865
866 /**
867 * Method to calculate the last payment date for quarterly frequency code
868 * @param currentDate, fiscalYearEndDate, dayOfMonth
869 * @return lastPaymentDate
870 */
871 protected long getNumberOfPaymentsRemainingForQuarterlyFrequency(Date nextIncomeDueDate, Date lastPaymentDate, String dayOfMonth, String month) {
872 long totalPayments = 0;
873
874 Calendar calendar = setCaledarWithMonth(month, nextIncomeDueDate);
875 setCalendarWithDays(calendar, dayOfMonth);
876
877 if (calendar.getTime().before(lastPaymentDate)) {
878 totalPayments = totalPayments + 1;
879 }
880 else {
881 return totalPayments;
882 }
883
884 while (calendar.getTime().before(lastPaymentDate)) {
885 calendar.add(Calendar.MONTH, 3);
886 totalPayments = totalPayments + 1;
887 }
888
889 return totalPayments;
890 }
891
892 /**
893 * Method to calculate the last payment date for SemiAnnually frequency code
894 * @param currentDate, fiscalYearEndDate, dayOfMonth
895 * @return lastPaymentDate
896 */
897 protected long getNumberOfPaymentsRemainingForSemiAnnuallyDate(Date nextIncomeDueDate, Date lastPaymentDate, String dayOfMonth, String month) {
898 long totalPayments = 0;
899
900 Calendar calendar = setCaledarWithMonth(month, nextIncomeDueDate);
901 setCalendarWithDays(calendar, dayOfMonth);
902
903 if (calendar.getTime().before(lastPaymentDate)) {
904 totalPayments = totalPayments + 1;
905 }
906 else {
907 return totalPayments;
908 }
909
910 while (calendar.getTime().before(lastPaymentDate)) {
911 calendar.add(Calendar.MONTH, 6);
912 totalPayments = totalPayments + 1;
913 }
914
915 return totalPayments;
916 }
917
918 /**
919 * Method to calculate the last payment date for Annually frequency code
920 * @param currentDate, fiscalYearEndDate, dayOfMonth
921 * @return lastPaymentDate
922 */
923 protected long getNumberOfPaymentsRemainingForAnnuallyDate(Date nextIncomeDueDate, Date lastPaymentDate, String dayOfMonth, String month) {
924 long totalPayments = 0;
925
926 Calendar calendar = setCaledarWithMonth(month, nextIncomeDueDate);
927 setCalendarWithDays(calendar, dayOfMonth);
928
929 if (calendar.getTime().before(lastPaymentDate)) {
930 totalPayments = totalPayments + 1;
931 }
932 else {
933 return totalPayments;
934 }
935
936 while (calendar.getTime().before(lastPaymentDate)) {
937 calendar.add(Calendar.YEAR, 1);
938 totalPayments = totalPayments + 1;
939 }
940
941 return totalPayments;
942 }
943
944 /**
945 * calculates the remainder of fiscal year estimated income for stocks
946 *
947 * @param security
948 * @param holdingTaxLot
949 * @return amount
950 */
951 protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForStocks(Security security, HoldingTaxLot holdingTaxLot) {
952 BigDecimal amount = BigDecimal.ZERO;
953
954 if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) {
955 return amount;
956 }
957
958 String incomePayFrequency = security.getIncomePayFrequency();
959 Date nextIncomeDueDate = security.getIncomeNextPayDate();
960
961 if (ObjectUtils.isNull(nextIncomeDueDate)) {
962 return amount;
963 }
964
965 Date fiscalYearEndDate = getFiscalYearEndDate();
966
967 // BONDS - rule 4.a
968 if (nextIncomeDueDate.after(fiscalYearEndDate)) {
969 return BigDecimal.ZERO;
970 }
971
972 int numberOfMonthsRemaing = getNumberOfMonthsRemaining(fiscalYearEndDate, nextIncomeDueDate);
973
974 if (nextIncomeDueDate.before(fiscalYearEndDate) && numberOfMonthsRemaing < 4) {
975 return BigDecimal.ZERO;
976 }
977
978 long quartersLeftToFiscalYear = getQuartersLeftToFiscalYear(fiscalYearEndDate);
979
980 //calculate holding units times security rate....
981 amount = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
982
983 // now multiply the above amount by 4 to get amount for 4 quarters or for the year...
984 amount = KEMCalculationRoundingHelper.divide(amount, BigDecimal.valueOf(4), EndowConstants.Scale.SECURITY_MARKET_VALUE);
985
986 //now compute the amount for the quarters remaining in the fiscal year....
987 amount = KEMCalculationRoundingHelper.multiply(amount, BigDecimal.valueOf(quartersLeftToFiscalYear), EndowConstants.Scale.SECURITY_MARKET_VALUE);
988
989 return amount;
990 }
991
992 /**
993 * Helper method to calculate the quarter number of the fiscal year.
994 *
995 * @param nextIncomeDueDate
996 * @return quarterOfFiscalYear
997 */
998 protected int getQuartersLeftToFiscalYear(Date fiscalYearEndDate) {
999 int numberOfMonthsRemaing = getNumberOfMonthsRemaining(fiscalYearEndDate, kEMService.getCurrentDate());
1000 return Math.round(numberOfMonthsRemaing / 3);
1001 }
1002
1003 /**
1004 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getHoldingMarketValueSumForSecurity(java.lang.String)
1005 */
1006 public BigDecimal getHoldingMarketValueSumForSecurity(String securityId) {
1007 BigDecimal sum = BigDecimal.ZERO;
1008
1009 List<CurrentTaxLotBalance> currentTaxLotBalances = (List<CurrentTaxLotBalance>) currentTaxLotBalanceDao.getAllCurrentTaxLotBalanceEntriesForSecurity(securityId);
1010
1011 if (currentTaxLotBalances != null) {
1012 for (CurrentTaxLotBalance currentTaxLotBalance : currentTaxLotBalances) {
1013 if (currentTaxLotBalance.getHoldingMarketValue() != null) {
1014 sum = sum.add(currentTaxLotBalance.getHoldingMarketValue());
1015 }
1016 }
1017 }
1018
1019 return sum;
1020 }
1021
1022 /**
1023 * @see org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getHoldingMarketValue(HoldingTaxLot, String)
1024 */
1025 public BigDecimal getHoldingMarketValue(HoldingTaxLot holdingTaxLot, String securityId) {
1026 BigDecimal holdingMarketValue = BigDecimal.ZERO;
1027
1028 Security security = securityService.getByPrimaryKey(securityId);
1029
1030 String classCodeType = security.getClassCode().getClassCodeType();
1031
1032 if (EndowConstants.ClassCodeTypes.ALTERNATIVE_INVESTMENT.equalsIgnoreCase(classCodeType)) {
1033 BigDecimal totalCashActivity = transactionArchiveDao.getTransactionArchivesTotalCashActivity(holdingTaxLot.getKemid(), securityId);
1034 return (security.getSecurityValueByMarket().subtract(totalCashActivity));
1035 }
1036 // calculations for BONDS
1037 if (EndowConstants.ClassCodeTypes.BOND.equalsIgnoreCase(classCodeType)) {
1038 holdingMarketValue = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getUnitValue(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
1039 holdingMarketValue = KEMCalculationRoundingHelper.divide(holdingMarketValue, BigDecimal.valueOf(100), EndowConstants.Scale.SECURITY_MARKET_VALUE);
1040 return holdingMarketValue;
1041 }
1042
1043 //other cases...
1044 holdingMarketValue = KEMCalculationRoundingHelper.multiply(holdingTaxLot.getUnits(), security.getUnitValue(), EndowConstants.Scale.SECURITY_MARKET_VALUE);
1045
1046 return holdingMarketValue;
1047 }
1048
1049 /**
1050 * Gets the businessObjectService.
1051 *
1052 * @return businessObjectService
1053 */
1054 protected BusinessObjectService getBusinessObjectService() {
1055 return businessObjectService;
1056 }
1057
1058 /**
1059 * Sets the businessObjectService.
1060 *
1061 * @param businessObjectService
1062 */
1063 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
1064 this.businessObjectService = businessObjectService;
1065 }
1066
1067 /**
1068 * Gets the securityService.
1069 *
1070 * @return securityService
1071 */
1072 protected SecurityService getSecurityService() {
1073 return securityService;
1074 }
1075
1076 /**
1077 * Sets the securityService.
1078 *
1079 * @param securityService
1080 */
1081 public void setSecurityService(SecurityService securityService) {
1082 this.securityService = securityService;
1083 }
1084
1085 /**
1086 * gets the kEMService.
1087 *
1088 * @param kEMService
1089 */
1090 protected KEMService getkEMService() {
1091 return kEMService;
1092 }
1093
1094 /**
1095 * Sets the kEMService.
1096 *
1097 * @param kEMService
1098 */
1099 public void setkEMService(KEMService kEMService) {
1100 this.kEMService = kEMService;
1101 }
1102
1103 public void setCurrentTaxLotBalanceDao(CurrentTaxLotBalanceDao currentTaxLotBalanceDao) {
1104 this.currentTaxLotBalanceDao = currentTaxLotBalanceDao;
1105 }
1106
1107
1108 /**
1109 * Gets the transactionArchiveDao attribute.
1110 * @return Returns the transactionArchiveDao.
1111 */
1112 protected TransactionArchiveDao getTransactionArchiveDao() {
1113 return transactionArchiveDao;
1114 }
1115
1116 /**
1117 * Sets the transactionArchiveDao attribute value.
1118 * @param transactionArchiveDao The transactionArchiveDao to set.
1119 */
1120 public void setTransactionArchiveDao(TransactionArchiveDao transactionArchiveDao) {
1121 this.transactionArchiveDao = transactionArchiveDao;
1122 }
1123 }