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 }