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 }