/** * @see * org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalanceSecurityUnitValue(String) * Method to get the security unit value for the current balance tax lot record * @param securityId * @return securityUnitValue */ public BigDecimal getCurrentTaxLotBalanceSecurityUnitValue(String securityId) { BigDecimal securityUnitValue = BigDecimal.ZERO; Security security = securityService.getByPrimaryKey(securityId); return security.getUnitValue(); }
/** * @org * .kuali.kfs.module.endow.document.service.CurrentTaxLotService#getCurrentTaxLotBalancesForMatchingSecurityClassCode(String) */ public Collection<CurrentTaxLotBalance> getCurrentTaxLotBalancesForMatchingSecurityClassCode( String securityClassCode) { Collection<CurrentTaxLotBalance> currentTaxLotBalances = new ArrayList(); Collection<Security> securities = new ArrayList(); if (StringUtils.isNotBlank(securityClassCode)) { Map criteria = new HashMap(); if (dataDictionaryService.getAttributeForceUppercase( Security.class, EndowPropertyConstants.SECURITY_CLASS_CODE)) { securityClassCode = securityClassCode.toUpperCase(); } criteria.put(EndowPropertyConstants.SECURITY_CLASS_CODE, securityClassCode); securities = businessObjectService.findMatching(Security.class, criteria); for (Security security : securities) { criteria.clear(); criteria.put(EndowPropertyConstants.CURRENT_TAX_LOT_BALANCE_SECURITY_ID, security.getId()); currentTaxLotBalances.addAll( businessObjectService.findMatching(HoldingHistory.class, criteria)); } } return currentTaxLotBalances; }
/** * Validates that the validateTaxLotsCostAndTransactionAmountLessOrEqualToSecurityCommitment * returns false when the SECURITY_ID has a class code type of A (Alternative Investments), and * the total END_HLDG_TAX_LOT_T: HLDG_COST for the SECURITY_ID plus the END_TRAN_LN_T: TRAN_AMT * exceeds the value in END_SEC_T: CMTMNT_AMT for the Security */ public void testValidateTaxLotsCostAndTransactionAmountLessOrEqualToSecurityCommitment_False() { KEMID kemid = KemIdFixture.OPEN_KEMID_RECORD.createKemidRecord(); // need to insert into END_HLDG_TAX_LOT_REBAL_T TABLE because of constraints.... HoldingTaxLotRebalanceFixture.HOLDING_TAX_LOT_REBALANCE_RECORD .createHoldingTaxLotRebalanceRecord(); HoldingTaxLot holdingTaxLot = HoldingTaxLotFixture.HOLDING_TAX_LOT_RECORD.createHoldingTaxLotRecord(); SecurityReportingGroup reportingGroup = SecurityReportingGroupFixture.REPORTING_GROUP.createSecurityReportingGroup(); EndowmentTransactionCode endowmentTransactionCode = EndowmentTransactionCodeFixture.INCOME_TRANSACTION_CODE.createEndowmentTransactionCode(); ClassCode classCode = ClassCodeFixture.ALTERNATIVE_INVESTMENT_CLASS_CODE.createClassCodeRecord(); Security security = SecurityFixture.ALTERNATIVE_INVEST_ACTIVE_SECURITY.createSecurityRecord(); security.setCommitmentAmount(BigDecimal.ZERO); document.getTargetTransactionSecurity().setSecurityID(security.getId()); document.getTargetTransactionSecurity().setSecurity(security); EndowmentTransactionLine endowmentTargetTransactionLine = EndowmentTransactionLineFixture.ENDOWMENT_TRANSACTIONAL_LINE_POSITIVE_AMT .createEndowmentTransactionLine(false); document.addTargetTransactionLine( (EndowmentTargetTransactionLine) endowmentTargetTransactionLine); assetIncreaseDocumentTaxLotsService.updateTransactionLineTaxLots( document, endowmentTargetTransactionLine); assertFalse( rule.validateTaxLotsCostAndTransactionAmountLessOrEqualToSecurityCommitment(document)); }
/** * @see * org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getNextTwelveMonthsEstimatedValue(String) * Method to calculate Next Twelve Months Estimated value * @param securityId * @return nextTwelveMonthsEstimatedValue */ public BigDecimal getNextTwelveMonthsEstimatedValue( HoldingTaxLot holdingTaxLot, String securityId) { BigDecimal nextTweleveMonthsEstimatedValue = BigDecimal.ZERO; Security security = securityService.getByPrimaryKey(securityId); return KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); }
/** * calculates the remainder of fiscal year estimated income for pooled funds * * @param security * @param holdingTaxLot * @return amount */ protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForPooledFunds( Security security, HoldingTaxLot holdingTaxLot) { BigDecimal amount = BigDecimal.ZERO; if (ObjectUtils.isNull(security.getIncomeNextPayDate()) || ObjectUtils.isNull(security.getFrequencyCode())) { return amount; } Date nextIncomeDueDate = security.getIncomeNextPayDate(); if (ObjectUtils.isNull(nextIncomeDueDate)) { return amount; } Date fiscalYearEndDate = getFiscalYearEndDate(); // BONDS - rule 4.a if (nextIncomeDueDate.after(fiscalYearEndDate)) { return BigDecimal.ZERO; } // rule 4.b if (nextIncomeDueDate.before(fiscalYearEndDate)) { String incomePayFrequency = security.getIncomePayFrequency(); if (ObjectUtils.isNull(incomePayFrequency)) { return amount; } Date lastPaymentDate = getLastPaymentDate(incomePayFrequency, fiscalYearEndDate); long paymentsRemaining = getTotalPaymentsRemaining( lastPaymentDate, fiscalYearEndDate, incomePayFrequency, nextIncomeDueDate); long totalNumberOfPayments = kEMService.getTotalNumberOfPaymentsForFiscalYear(); amount = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); amount = amount.multiply(BigDecimal.valueOf(paymentsRemaining)); amount = KEMCalculationRoundingHelper.divide( amount, BigDecimal.valueOf(totalNumberOfPayments), EndowConstants.Scale.SECURITY_MARKET_VALUE); amount = amount.add(holdingTaxLot.getCurrentAccrual()); } return amount; }
/** * calculates the remainder of fiscal year estimated income for stocks * * @param security * @param holdingTaxLot * @return amount */ protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForStocks( Security security, HoldingTaxLot holdingTaxLot) { BigDecimal amount = BigDecimal.ZERO; if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) { return amount; } String incomePayFrequency = security.getIncomePayFrequency(); Date nextIncomeDueDate = security.getIncomeNextPayDate(); if (ObjectUtils.isNull(nextIncomeDueDate)) { return amount; } Date fiscalYearEndDate = getFiscalYearEndDate(); // BONDS - rule 4.a if (nextIncomeDueDate.after(fiscalYearEndDate)) { return BigDecimal.ZERO; } int numberOfMonthsRemaing = getNumberOfMonthsRemaining(fiscalYearEndDate, nextIncomeDueDate); if (nextIncomeDueDate.before(fiscalYearEndDate) && numberOfMonthsRemaing < 4) { return BigDecimal.ZERO; } long quartersLeftToFiscalYear = getQuartersLeftToFiscalYear(fiscalYearEndDate); // calculate holding units times security rate.... amount = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); // now multiply the above amount by 4 to get amount for 4 quarters or for the year... amount = KEMCalculationRoundingHelper.divide( amount, BigDecimal.valueOf(4), EndowConstants.Scale.SECURITY_MARKET_VALUE); // now compute the amount for the quarters remaining in the fiscal year.... amount = KEMCalculationRoundingHelper.multiply( amount, BigDecimal.valueOf(quartersLeftToFiscalYear), EndowConstants.Scale.SECURITY_MARKET_VALUE); return amount; }
/** * @see * org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getNextFiscalYearInvestmentIncome(HoldingTaxLot, * String) Method to calculate next fiscal year investment income * @param securityId * @return nextFiscalyearInvestmentIncome */ public BigDecimal getNextFiscalYearInvestmentIncome( HoldingTaxLot holdingTaxLot, String securityId) { BigDecimal nextFiscalyearInvestmentIncome = BigDecimal.ZERO; Security security = securityService.getByPrimaryKey(securityId); nextFiscalyearInvestmentIncome = KEMCalculationRoundingHelper.multiply( security.getNextFiscalYearDistributionAmount(), holdingTaxLot.getUnits(), EndowConstants.Scale.SECURITY_MARKET_VALUE); return nextFiscalyearInvestmentIncome; }
/** Validates that isSecurityActive returns false when an inactive security is added. */ public void testActiveSecurity_False() { // add security details SecurityReportingGroup reportingGroup = SecurityReportingGroupFixture.REPORTING_GROUP.createSecurityReportingGroup(); EndowmentTransactionCode endowmentTransactionCode = EndowmentTransactionCodeFixture.INCOME_TRANSACTION_CODE.createEndowmentTransactionCode(); ClassCode classCode = ClassCodeFixture.LIABILITY_CLASS_CODE.createClassCodeRecord(); Security security = SecurityFixture.INACTIVE_SECURITY.createSecurityRecord(); EndowmentTargetTransactionSecurity targetTransactionSecurity = new EndowmentTargetTransactionSecurity(); targetTransactionSecurity.setSecurityID(security.getId()); targetTransactionSecurity.setSecurity(security); document.setTargetTransactionSecurity(targetTransactionSecurity); assertFalse(rule.isSecurityActive(document, false)); }
/** * calculates the remainder of fiscal year estimated income for cash * * @param security * @param holdingTaxLot * @return amount */ protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForCash( Security security, HoldingTaxLot holdingTaxLot) { BigDecimal amount = BigDecimal.ZERO; if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) { return amount; } Date nextIncomeDueDate = security.getIncomeNextPayDate(); Date fiscalYearEndDate = getFiscalYearEndDate(); String incomePayFrequency = security.getIncomePayFrequency(); if (ObjectUtils.isNull(nextIncomeDueDate) || ObjectUtils.isNull(incomePayFrequency)) { return amount; } // BONDS - rule 3.a if (nextIncomeDueDate.after(fiscalYearEndDate)) { return BigDecimal.ZERO; } // rule 3.b if (nextIncomeDueDate.before(fiscalYearEndDate)) { Date lastPaymentDate = getLastPaymentDate(incomePayFrequency, fiscalYearEndDate); long daysToLastPayment = getTotalDaysToLastPayment(lastPaymentDate, nextIncomeDueDate); amount = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); amount = amount.multiply(BigDecimal.valueOf(daysToLastPayment)); amount = KEMCalculationRoundingHelper.divide( amount, BigDecimal.valueOf(EndowConstants.NUMBER_OF_DAYS_IN_YEAR), EndowConstants.Scale.SECURITY_MARKET_VALUE); amount = amount.add(holdingTaxLot.getCurrentAccrual()); } return amount; }
/** * calculates the remainder of fiscal year estimated income for bonds * * @param security * @param holdingTaxLot * @return amount */ protected BigDecimal getRemainderOfFiscalYearEstimatedIncomeForBonds( Security security, HoldingTaxLot holdingTaxLot) { BigDecimal amount = BigDecimal.ZERO; if (ObjectUtils.isNull(security.getIncomeRate()) || security.getIncomeRate().compareTo(BigDecimal.ZERO) == 0) { return amount; } Date nextIncomeDueDate = security.getIncomeNextPayDate(); if (ObjectUtils.isNull(nextIncomeDueDate)) { return amount; } Date fiscalYearEndDate = getFiscalYearEndDate(); // BONDS - rule 2.a if (nextIncomeDueDate.after(fiscalYearEndDate)) { return BigDecimal.ZERO; } int numberOfMonthsRemaining = getNumberOfMonthsRemaining(fiscalYearEndDate, nextIncomeDueDate); // rule 2.b if (nextIncomeDueDate.before(fiscalYearEndDate) && numberOfMonthsRemaining < EndowConstants.NUMBER_OF_MONTHS_REMAINING) { amount = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); amount = KEMCalculationRoundingHelper.divide( amount, BigDecimal.valueOf(2), EndowConstants.Scale.SECURITY_MARKET_VALUE); } else { amount = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getIncomeRate(), EndowConstants.Scale.SECURITY_MARKET_VALUE); } return amount; }
/** * @see * org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getRemainderOfFiscalYearEstimatedIncome(HoldingTaxLot, * String) Method to calculate remainder of fiscal year estimated income * @param securityId * @return remainderOfFiscalYearEstimatedIncome */ public BigDecimal getRemainderOfFiscalYearEstimatedIncome( HoldingTaxLot holdingTaxLot, String securityId) { BigDecimal incomeAmount = BigDecimal.ZERO; Security security = securityService.getByPrimaryKey(securityId); String classCodeType = security.getClassCode().getClassCodeType(); if (EndowConstants.ClassCodeTypes.ALTERNATIVE_INVESTMENT.equalsIgnoreCase(classCodeType)) { return BigDecimal.ZERO; } // calculations for BONDS if (EndowConstants.ClassCodeTypes.BOND.equalsIgnoreCase(classCodeType)) { return getRemainderOfFiscalYearEstimatedIncomeForBonds(security, holdingTaxLot); } // calculations for CASH if (EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS.equalsIgnoreCase(classCodeType)) { return getRemainderOfFiscalYearEstimatedIncomeForCash(security, holdingTaxLot); } // calculations for LIABILITIES if (EndowConstants.ClassCodeTypes.LIABILITY.equalsIgnoreCase(classCodeType)) { return BigDecimal.ZERO; } // calculations for OTHER if (EndowConstants.ClassCodeTypes.OTHER.equalsIgnoreCase(classCodeType)) { return BigDecimal.ZERO; } // calculations for POOLED FUNDS if (EndowConstants.ClassCodeTypes.POOLED_INVESTMENT.equalsIgnoreCase(classCodeType)) { return getRemainderOfFiscalYearEstimatedIncomeForPooledFunds(security, holdingTaxLot); } // calculations for STOCKS if (EndowConstants.ClassCodeTypes.STOCKS.equalsIgnoreCase(classCodeType)) { return getRemainderOfFiscalYearEstimatedIncomeForStocks(security, holdingTaxLot); } return incomeAmount; }
/** * @see * org.kuali.kfs.module.endow.document.service.CurrentTaxLotService#getHoldingMarketValue(HoldingTaxLot, * String) */ public BigDecimal getHoldingMarketValue(HoldingTaxLot holdingTaxLot, String securityId) { BigDecimal holdingMarketValue = BigDecimal.ZERO; Security security = securityService.getByPrimaryKey(securityId); String classCodeType = security.getClassCode().getClassCodeType(); if (EndowConstants.ClassCodeTypes.ALTERNATIVE_INVESTMENT.equalsIgnoreCase(classCodeType)) { String kemid = holdingTaxLot.getKemid(); if (dataDictionaryService.getAttributeForceUppercase( TransactionArchive.class, EndowPropertyConstants.TRANSACTION_ARCHIVE_KEM_ID)) { kemid = kemid.toUpperCase(); } BigDecimal totalCashActivity = transactionArchiveDao.getTransactionArchivesTotalCashActivity(kemid, securityId); return (security.getSecurityValueByMarket().subtract(totalCashActivity)); } // calculations for BONDS if (EndowConstants.ClassCodeTypes.BOND.equalsIgnoreCase(classCodeType)) { holdingMarketValue = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getUnitValue(), EndowConstants.Scale.SECURITY_MARKET_VALUE); holdingMarketValue = KEMCalculationRoundingHelper.divide( holdingMarketValue, BigDecimal.valueOf(100), EndowConstants.Scale.SECURITY_MARKET_VALUE); return holdingMarketValue; } // other cases... holdingMarketValue = KEMCalculationRoundingHelper.multiply( holdingTaxLot.getUnits(), security.getUnitValue(), EndowConstants.Scale.SECURITY_MARKET_VALUE); return holdingMarketValue; }
/** * Validates that validateSecurityClassCodeTypeNotLiability returns true when a security with a * class code other that Liability is added. */ public void testLiabilityClassCode_True() { // add security details SecurityReportingGroup reportingGroup = SecurityReportingGroupFixture.REPORTING_GROUP.createSecurityReportingGroup(); EndowmentTransactionCode endowmentTransactionCode = EndowmentTransactionCodeFixture.INCOME_TRANSACTION_CODE.createEndowmentTransactionCode(); ClassCode classCode = ClassCodeFixture.NOT_LIABILITY_CLASS_CODE.createClassCodeRecord(); Security security = SecurityFixture.ACTIVE_SECURITY.createSecurityRecord(); security.setClassCode(classCode); security.setSecurityClassCode(classCode.getCode()); EndowmentTargetTransactionSecurity targetTransactionSecurity = new EndowmentTargetTransactionSecurity(); targetTransactionSecurity.setSecurityID(security.getId()); targetTransactionSecurity.setSecurity(security); document.getTargetTransactionSecurities().add(targetTransactionSecurity); assertTrue(rule.validateSecurityClassCodeTypeNotLiability(document, false)); }
/** * @see * org.kuali.kfs.module.endow.document.service.UpdateTaxLotsBasedOnAccMethodAndTransSubtypeService#updateTransactionLineTaxLots(boolean, * org.kuali.kfs.module.endow.document.EndowmentTaxLotLinesDocument, * org.kuali.kfs.module.endow.businessobject.EndowmentTransactionLine) */ public void updateTransactionLineTaxLots( boolean isUpdate, EndowmentTaxLotLinesDocument endowmentTaxLotLinesDocument, EndowmentTransactionLine transLine) { EndowmentTransactionSecurity endowmentTransactionSecurity = endowmentTaxLotLinesDocument.getSourceTransactionSecurity(); String accountingMethod = parameterService.getParameterValueAsString( KfsParameterConstants.ENDOWMENT_ALL.class, EndowParameterKeyConstants.TAX_LOTS_ACCOUNTING_METHOD); Security security = securityService.getByPrimaryKey(endowmentTransactionSecurity.getSecurityID()); if (ObjectUtils.isNotNull(security)) { // In the Asset Decrease document, if transaction sub type is non-cash and IF the user inserts // an amount in the // transaction amount, that amount along with the units sill be used to generate the // transaction tax lot lines. The // amount will not be calculated by the addition of the transaction line. In the event the // user has entered an amount in // the transaction amount field, that amount along with the units will be spread // proportionately among the tax lots. if (endowmentTaxLotLinesDocument instanceof AssetDecreaseDocument && EndowConstants.TransactionSubTypeCode.NON_CASH.equalsIgnoreCase( endowmentTaxLotLinesDocument.getTransactionSubTypeCode()) && transLine.getTransactionAmount() != null && transLine.getTransactionAmount().bigDecimalValue().compareTo(BigDecimal.ZERO) != 0) { updateTaxLotsForSubTypeNonCashAndTransAmtNonZero( isUpdate, endowmentTransactionSecurity, transLine); } else { if (EndowConstants.TaxLotsAccountingMethodOptions.AVERAGE_BALANCE.equalsIgnoreCase( accountingMethod) || (EndowConstants.TaxLotsAccountingMethodOptions.FIFO.equalsIgnoreCase( accountingMethod) && !security.getClassCode().isTaxLotIndicator())) { if (EndowConstants.TransactionSubTypeCode.CASH.equalsIgnoreCase( endowmentTaxLotLinesDocument.getTransactionSubTypeCode())) { updateTaxLotsForAccountingMethodAverageBalance( true, isUpdate, endowmentTransactionSecurity, transLine); } if (EndowConstants.TransactionSubTypeCode.NON_CASH.equalsIgnoreCase( endowmentTaxLotLinesDocument.getTransactionSubTypeCode())) { updateTaxLotsForAccountingMethodAverageBalance( false, isUpdate, endowmentTransactionSecurity, transLine); setTransactionLineTotal(transLine); } } if ((EndowConstants.TaxLotsAccountingMethodOptions.FIFO.equalsIgnoreCase(accountingMethod) || EndowConstants.TaxLotsAccountingMethodOptions.LIFO.equalsIgnoreCase( accountingMethod)) && security.getClassCode().isTaxLotIndicator()) { boolean isFIFO = EndowConstants.TaxLotsAccountingMethodOptions.FIFO.equalsIgnoreCase(accountingMethod); if (EndowConstants.TransactionSubTypeCode.CASH.equalsIgnoreCase( endowmentTaxLotLinesDocument.getTransactionSubTypeCode())) { updateTaxLotsForAccountingMethodFIFOorLIFO( true, isUpdate, isFIFO, endowmentTransactionSecurity, transLine); } if (EndowConstants.TransactionSubTypeCode.NON_CASH.equalsIgnoreCase( endowmentTaxLotLinesDocument.getTransactionSubTypeCode())) { updateTaxLotsForAccountingMethodFIFOorLIFO( false, isUpdate, isFIFO, endowmentTransactionSecurity, transLine); setTransactionLineTotal(transLine); } } } } }