/**
   * @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;
  }
  /**
   * @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);
          }
        }
      }
    }
  }