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.dataaccess.impl; 017 018 import java.math.BigDecimal; 019 import java.sql.Date; 020 import java.util.ArrayList; 021 import java.util.Collection; 022 import java.util.HashMap; 023 import java.util.Iterator; 024 import java.util.List; 025 import java.util.Map; 026 027 import org.apache.commons.lang.StringUtils; 028 import org.apache.ojb.broker.query.Criteria; 029 import org.apache.ojb.broker.query.QueryByCriteria; 030 import org.apache.ojb.broker.query.QueryFactory; 031 import org.apache.ojb.broker.query.ReportQueryByCriteria; 032 import org.kuali.kfs.module.endow.EndowConstants; 033 import org.kuali.kfs.module.endow.EndowPropertyConstants; 034 import org.kuali.kfs.module.endow.EndowConstants.IncomePrincipalIndicator; 035 import org.kuali.kfs.module.endow.businessobject.FeeClassCode; 036 import org.kuali.kfs.module.endow.businessobject.FeeMethod; 037 import org.kuali.kfs.module.endow.businessobject.FeeSecurity; 038 import org.kuali.kfs.module.endow.businessobject.HoldingHistory; 039 import org.kuali.kfs.module.endow.businessobject.KEMID; 040 import org.kuali.kfs.module.endow.businessobject.PooledFundValue; 041 import org.kuali.kfs.module.endow.businessobject.Security; 042 import org.kuali.kfs.module.endow.dataaccess.HoldingHistoryDao; 043 import org.kuali.kfs.module.endow.dataaccess.SecurityDao; 044 import org.kuali.kfs.module.endow.document.service.MonthEndDateService; 045 import org.kuali.kfs.module.endow.util.KEMCalculationRoundingHelper; 046 import org.kuali.kfs.sys.context.SpringContext; 047 import org.kuali.rice.kns.dao.impl.PlatformAwareDaoBaseOjb; 048 import org.kuali.rice.kns.service.DataDictionaryService; 049 import org.kuali.rice.kns.util.KualiInteger; 050 051 public class HoldingHistoryDaoOjb extends PlatformAwareDaoBaseOjb implements HoldingHistoryDao { 052 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(HoldingHistoryDaoOjb.class); 053 054 protected MonthEndDateService monthEndDateService; 055 protected SecurityDao securityDao; 056 057 /** 058 * Prepares the criteria and selects the records from END_HLDG_HIST_T table 059 */ 060 protected Collection<HoldingHistory> getHoldingHistoryForBlance(FeeMethod feeMethod) { 061 Collection<HoldingHistory> holdingHistory = new ArrayList(); 062 063 Collection incomePrincipalValues = new ArrayList(); 064 incomePrincipalValues.add(EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_INCOME); 065 incomePrincipalValues.add(EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_PRINCIPAL); 066 067 Criteria criteria = new Criteria(); 068 069 if (feeMethod.getFeeBaseCode().equalsIgnoreCase(EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_INCOME_AND_PRINCIPAL)) { 070 criteria.addIn(EndowPropertyConstants.HOLDING_HISTORY_INCOME_PRINCIPAL_INDICATOR, incomePrincipalValues); 071 } 072 else { 073 if (feeMethod.getFeeBaseCode().equalsIgnoreCase(EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_INCOME)) { 074 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_INCOME_PRINCIPAL_INDICATOR, EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_INCOME); 075 } 076 077 if (feeMethod.getFeeBaseCode().equalsIgnoreCase(EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_PRINCIPAL)) { 078 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_INCOME_PRINCIPAL_INDICATOR, EndowConstants.FeeMethod.FEE_BASE_CODE_VALUE_FOR_PRINCIPAL); 079 } 080 } 081 082 Collection securityClassCodes = new ArrayList(); 083 Collection securityIds = new ArrayList(); 084 085 if (feeMethod.getFeeByClassCode() && feeMethod.getFeeBySecurityCode()) { 086 securityClassCodes = getSecurityClassCodes(feeMethod.getCode()); 087 securityIds = getSecurityIds(feeMethod.getCode()); 088 089 securityIds.addAll(securityClassCodes); 090 if (securityIds.size() > 0) { 091 criteria.addIn(EndowPropertyConstants.HOLDING_HISTORY_SECURITY_ID, securityIds); 092 } 093 } 094 else { 095 if (feeMethod.getFeeByClassCode()) { 096 securityClassCodes = getSecurityClassCodes(feeMethod.getCode()); 097 if (securityClassCodes.size() > 0) { 098 criteria.addIn(EndowPropertyConstants.HOLDING_HISTORY_SECURITY_ID, securityClassCodes); 099 } 100 } 101 102 if (feeMethod.getFeeBySecurityCode()) { 103 securityIds = getSecurityIds(feeMethod.getCode()); 104 if (securityIds.size() > 0) { 105 criteria.addIn(EndowPropertyConstants.HOLDING_HISTORY_SECURITY_ID, securityIds); 106 } 107 } 108 } 109 110 QueryByCriteria query = QueryFactory.newQuery(HoldingHistory.class, criteria); 111 112 holdingHistory = getPersistenceBrokerTemplate().getCollectionByQuery(query); 113 114 return holdingHistory; 115 } 116 117 /** 118 * Gets the security codes for a given securityClassCode in END_FEE_CLS_CD_T table 119 * @feeMethodCode FEE_MTH 120 * @return securityCodes 121 */ 122 protected Collection getSecurityClassCodes(String feeMethodCode) { 123 Collection securityClassCodes = new ArrayList(); 124 Collection<FeeClassCode> feeClassCodes = new ArrayList(); 125 126 if (StringUtils.isNotBlank(feeMethodCode)) { 127 Map<String, String> crit = new HashMap<String, String>(); 128 129 if (SpringContext.getBean(DataDictionaryService.class).getAttributeForceUppercase(FeeClassCode.class, EndowPropertyConstants.FEE_METHOD_CODE)) { 130 feeMethodCode = feeMethodCode.toUpperCase(); 131 } 132 133 Criteria criteria = new Criteria(); 134 criteria.addEqualTo(EndowPropertyConstants.FEE_METHOD_CODE, feeMethodCode); 135 criteria.addEqualTo(EndowPropertyConstants.FEE_CLASS_CODE_INCLUDE, EndowConstants.YES); 136 137 QueryByCriteria query = QueryFactory.newQuery(FeeClassCode.class, criteria); 138 139 feeClassCodes = getPersistenceBrokerTemplate().getCollectionByQuery(query); 140 for (FeeClassCode feeClassCode : feeClassCodes) { 141 Collection <Security> securities = securityDao.getSecuritiesBySecurityClassCode(feeClassCode.getFeeClassCode()); 142 for (Security security : securities) { 143 securityClassCodes.add(security.getId()); 144 } 145 } 146 } 147 148 return securityClassCodes; 149 } 150 151 /** 152 * Gets the security ids for a given securityClassCode in END_FEE_SEC_T table 153 * @feeMethodCode FEE_MTH 154 * @return securityIds 155 */ 156 protected Collection getSecurityIds(String feeMethodCode) { 157 Collection securityIds = new ArrayList(); 158 Collection<FeeSecurity> feeSecuritys = new ArrayList(); 159 160 if (StringUtils.isNotBlank(feeMethodCode)) { 161 Map<String, String> crit = new HashMap<String, String>(); 162 163 if (SpringContext.getBean(DataDictionaryService.class).getAttributeForceUppercase(FeeSecurity.class, EndowPropertyConstants.FEE_METHOD_CODE)) { 164 feeMethodCode = feeMethodCode.toUpperCase(); 165 } 166 167 Criteria criteria = new Criteria(); 168 criteria.addEqualTo(EndowPropertyConstants.FEE_METHOD_CODE, feeMethodCode); 169 criteria.addEqualTo(EndowPropertyConstants.FEE_SECURITY_INCLUDE, EndowConstants.YES); 170 171 QueryByCriteria query = QueryFactory.newQuery(FeeSecurity.class, criteria); 172 173 feeSecuritys = getPersistenceBrokerTemplate().getCollectionByQuery(query); 174 for (FeeSecurity feeSecurity : feeSecuritys) { 175 securityIds.add(feeSecurity.getSecurityCode()); 176 } 177 } 178 179 return securityIds; 180 } 181 182 /** 183 * @see org.kuali.kfs.module.endow.dataaccess.HoldingHistoryDao#getHoldingHistoryTotalHoldingUnits(FeeMethod) 184 */ 185 public BigDecimal getHoldingHistoryTotalHoldingUnits(FeeMethod feeMethod) { 186 BigDecimal totalHoldingUnits = BigDecimal.ZERO; 187 188 Date lastProcessDate = feeMethod.getFeeLastProcessDate(); 189 Date mostRecentDate = monthEndDateService.getMostRecentDate(); 190 191 String feeBalanceTypeCode = feeMethod.getFeeBalanceTypeCode(); 192 193 Collection <HoldingHistory> holdingHistoryRecords = getHoldingHistoryForBlance(feeMethod); 194 for (HoldingHistory holdingHistory : holdingHistoryRecords) { 195 Date monthEndDate = monthEndDateService.getByPrimaryKey(holdingHistory.getMonthEndDateId()); 196 197 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_AVERAGE_UNITS) && (monthEndDate.compareTo(lastProcessDate) > 0)) { 198 totalHoldingUnits = totalHoldingUnits.add(holdingHistory.getUnits()); 199 } 200 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_MONTH_END_UNITS) && (mostRecentDate.compareTo(lastProcessDate) > 0)) { 201 totalHoldingUnits = totalHoldingUnits.add(holdingHistory.getUnits()); 202 } 203 } 204 205 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_AVERAGE_UNITS)) { 206 totalHoldingUnits = KEMCalculationRoundingHelper.divide(totalHoldingUnits, BigDecimal.valueOf(holdingHistoryRecords.size()), EndowConstants.Scale.SECURITY_UNIT_VALUE); 207 } 208 209 return totalHoldingUnits; 210 } 211 212 /** 213 * @see org.kuali.kfs.module.endow.dataaccess.HoldingHistoryDao#getHoldingHistoryTotalHoldingMarketValue(FeeMethod) 214 */ 215 public BigDecimal getHoldingHistoryTotalHoldingMarketValue(FeeMethod feeMethod) { 216 BigDecimal totalHoldingMarkteValue = BigDecimal.ZERO; 217 218 Date lastProcessDate = feeMethod.getFeeLastProcessDate(); 219 Date mostRecentDate = monthEndDateService.getMostRecentDate(); 220 221 String feeBalanceTypeCode = feeMethod.getFeeBalanceTypeCode(); 222 223 Collection <HoldingHistory> holdingHistoryRecords = getHoldingHistoryForBlance(feeMethod); 224 for (HoldingHistory holdingHistory : holdingHistoryRecords) { 225 Date monthEndDate = monthEndDateService.getByPrimaryKey(holdingHistory.getMonthEndDateId()); 226 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_AVERAGE_MARKET_VALUE) && (monthEndDate.compareTo(lastProcessDate) > 0)) { 227 totalHoldingMarkteValue = totalHoldingMarkteValue.add(holdingHistory.getMarketValue()); 228 } 229 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_MONTH_END_MARKET_VALUE) && (monthEndDate.compareTo(mostRecentDate) > 0)) { 230 totalHoldingMarkteValue = totalHoldingMarkteValue.add(holdingHistory.getMarketValue()); 231 } 232 } 233 234 if (feeBalanceTypeCode.equals(EndowConstants.FeeBalanceTypes.FEE_BALANCE_TYPE_VALUE_FOR_AVERAGE_MARKET_VALUE)) { 235 totalHoldingMarkteValue = KEMCalculationRoundingHelper.divide(totalHoldingMarkteValue, BigDecimal.valueOf(holdingHistoryRecords.size()), EndowConstants.Scale.SECURITY_UNIT_VALUE); 236 } 237 238 return totalHoldingMarkteValue; 239 } 240 241 /** 242 * 243 * @see org.kuali.kfs.module.endow.dataaccess.HoldingHistoryDao#getHoldingHistory(java.lang.String, java.lang.String) 244 */ 245 public List<HoldingHistory> getHoldingHistory(String kemid, KualiInteger medId) { 246 247 Criteria criteria = new Criteria(); 248 criteria.addEqualTo(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid); 249 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_MONTH_END_DATE_ID, medId); 250 QueryByCriteria qbc = QueryFactory.newQuery(HoldingHistory.class, criteria); 251 qbc.addOrderByAscending(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID); 252 253 return (List<HoldingHistory>) getPersistenceBrokerTemplate().getCollectionByQuery(qbc); 254 } 255 256 /** 257 * 258 * @see org.kuali.kfs.module.endow.dataaccess.HoldingHistoryDao#getHoldingHistoryByKemid(java.lang.String) 259 */ 260 public List<HoldingHistory> getHoldingHistoryByKemid(String kemid) { 261 262 Criteria criteria = new Criteria(); 263 criteria.addEqualTo(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid); 264 QueryByCriteria qbc = QueryFactory.newQuery(HoldingHistory.class, criteria); 265 qbc.addOrderByAscending(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID); 266 267 return (List<HoldingHistory>) getPersistenceBrokerTemplate().getCollectionByQuery(qbc); 268 } 269 270 public List<HoldingHistory> getHoldingHistoryByKemidIdAndMonthEndIdAndIpInd(String kemid, KualiInteger monthEndId, String ipInd) { 271 272 Criteria criteria = new Criteria(); 273 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_KEMID, kemid); 274 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_MONTH_END_DATE_ID, monthEndId); 275 criteria.addGreaterThan(EndowPropertyConstants.HOLDING_TAX_LOT_UNITS, BigDecimal.ZERO); 276 if (ipInd.equalsIgnoreCase(IncomePrincipalIndicator.INCOME) || ipInd.equalsIgnoreCase(IncomePrincipalIndicator.PRINCIPAL)) { 277 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_INCOME_PRINCIPAL_INDICATOR, ipInd); 278 } 279 280 QueryByCriteria qbc = QueryFactory.newQuery(HoldingHistory.class, criteria); 281 qbc.addOrderByAscending(EndowPropertyConstants.KEMID); 282 283 return (List<HoldingHistory>) getPersistenceBrokerTemplate().getCollectionByQuery(qbc); 284 285 } 286 287 /** 288 * Gets the sum of the specified attribute values 289 * 290 * @param kemid 291 * @param medId 292 * @param securityId 293 * @param ipInd 294 * @param attributeName 295 * @return 296 */ 297 public BigDecimal getSumOfHoldginHistoryAttribute(String attributeName, String kemid, KualiInteger medId, String securityId, String ipInd) { 298 299 BigDecimal total = BigDecimal.ZERO; 300 301 Criteria criteria = new Criteria(); 302 criteria.addEqualTo(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid); 303 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_MONTH_END_DATE_ID, medId); 304 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_SECURITY_ID, securityId); 305 criteria.addGreaterThan(EndowPropertyConstants.HOLDING_TAX_LOT_UNITS, BigDecimal.ZERO); 306 if (ipInd.equalsIgnoreCase(IncomePrincipalIndicator.INCOME) || ipInd.equalsIgnoreCase(IncomePrincipalIndicator.PRINCIPAL)) { 307 criteria.addEqualTo(EndowPropertyConstants.HOLDING_HISTORY_INCOME_PRINCIPAL_INDICATOR, ipInd); 308 } 309 310 ReportQueryByCriteria rqbc = QueryFactory.newReportQuery(HoldingHistory.class, criteria); 311 rqbc.setAttributes(new String[] {"sum(" + attributeName + ")"}); 312 rqbc.addGroupBy(attributeName); 313 Iterator<?> result = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(rqbc); 314 315 while (result.hasNext()) { 316 Object[] data = (Object[]) result.next(); 317 total = total.add((BigDecimal)data[0]); 318 } 319 320 return total; 321 } 322 323 /** 324 * Gets the monthEndDateService attribute. 325 * @return Returns the monthEndDateService. 326 */ 327 protected MonthEndDateService getMonthEndDateService() { 328 return monthEndDateService; 329 } 330 331 /** 332 * Sets the monthEndDateService attribute value. 333 * @param monthEndDateService The monthEndDateService to set. 334 */ 335 public void setMonthEndDateService(MonthEndDateService monthEndDateService) { 336 this.monthEndDateService = monthEndDateService; 337 } 338 339 /** 340 * Gets the securityDao attribute. 341 * @return Returns the securityDao. 342 */ 343 protected SecurityDao getSecurityDao() { 344 return securityDao; 345 } 346 347 /** 348 * Sets the securityDao attribute value. 349 * @param securityDao The securityDao to set. 350 */ 351 public void setSecurityDao(SecurityDao securityDao) { 352 this.securityDao = securityDao; 353 } 354 }