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.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.kuali.kfs.module.endow.EndowConstants;
024    import org.kuali.kfs.module.endow.EndowPropertyConstants;
025    import org.kuali.kfs.module.endow.businessobject.ClassCode;
026    import org.kuali.kfs.module.endow.businessobject.HoldingTaxLot;
027    import org.kuali.kfs.module.endow.businessobject.Security;
028    import org.kuali.kfs.module.endow.dataaccess.HoldingTaxLotDao;
029    import org.kuali.kfs.module.endow.document.service.ClassCodeService;
030    import org.kuali.kfs.module.endow.document.service.HoldingTaxLotService;
031    import org.kuali.kfs.module.endow.document.service.KEMService;
032    import org.kuali.kfs.module.endow.document.service.SecurityService;
033    import org.kuali.kfs.module.endow.util.KEMCalculationRoundingHelper;
034    import org.kuali.rice.kns.service.BusinessObjectService;
035    import org.kuali.rice.kns.util.ObjectUtils;
036    import org.springframework.transaction.annotation.Transactional;
037    
038    /**
039     * 
040     */
041    @Transactional
042    public class HoldingTaxLotServiceImpl implements HoldingTaxLotService {
043        protected HoldingTaxLotDao holdingTaxLotDao;
044        protected BusinessObjectService businessObjectService;
045        protected SecurityService securityService;
046        protected ClassCodeService classCodeService;
047        protected KEMService kEMService;
048    
049        /**
050         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getByPrimaryKey(java.lang.String, java.lang.String,
051         *      java.lang.String, int, java.lang.String)
052         */
053        public HoldingTaxLot getByPrimaryKey(String kemid, String securityId, String registrationCode, int lotNumber, String ipIndicator) {
054            Map<String, String> primaryKeys = new HashMap<String, String>();
055    
056            primaryKeys.put(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid);
057            primaryKeys.put(EndowPropertyConstants.HOLDING_TAX_LOT_SECURITY_ID, securityId);
058            primaryKeys.put(EndowPropertyConstants.HOLDING_TAX_LOT_REGISTRATION_CODE, registrationCode);
059            primaryKeys.put(EndowPropertyConstants.HOLDING_TAX_LOT_NUMBER, String.valueOf(lotNumber));
060            primaryKeys.put(EndowPropertyConstants.HOLDING_TAX_LOT_INCOME_PRINCIPAL_INDICATOR, ipIndicator);
061    
062            return (HoldingTaxLot) businessObjectService.findByPrimaryKey(HoldingTaxLot.class, primaryKeys);
063    
064        }
065    
066        /**
067         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLots(java.lang.String, java.lang.String,
068         *      java.lang.String, java.lang.String)
069         */
070        public List<HoldingTaxLot> getAllTaxLots(String kemid, String securityId, String registrationCode, String ipIndicator) {
071            Map<String, String> criteria = new HashMap<String, String>();
072    
073            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid);
074            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_SECURITY_ID, securityId);
075            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_REGISTRATION_CODE, registrationCode);
076            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_INCOME_PRINCIPAL_INDICATOR, ipIndicator);
077    
078            return (List<HoldingTaxLot>) businessObjectService.findMatching(HoldingTaxLot.class, criteria);
079        }
080    
081        /**
082         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLots()
083         */
084        public List<HoldingTaxLot> getAllTaxLots() {
085            return (List<HoldingTaxLot>) businessObjectService.findAll(HoldingTaxLot.class);
086        }
087    
088        /**
089         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLotsOrderByAcquiredDate(java.lang.String,
090         *      java.lang.String, java.lang.String, java.lang.String, boolean)
091         */
092        public List<HoldingTaxLot> getAllTaxLotsOrderByAcquiredDate(String kemid, String securityId, String registrationCode, String ipIndicator, boolean sortAscending) {
093            Map<String, String> criteria = new HashMap<String, String>();
094    
095            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid);
096            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_SECURITY_ID, securityId);
097            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_REGISTRATION_CODE, registrationCode);
098            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_INCOME_PRINCIPAL_INDICATOR, ipIndicator);
099    
100            return (List<HoldingTaxLot>) businessObjectService.findMatchingOrderBy(HoldingTaxLot.class, criteria, EndowPropertyConstants.HOLDING_TAX_LOT_ACQUIRED_DATE, sortAscending);
101        }
102    
103        /**
104         * Gets all tax lots on the following criteria: kemId and IPIndicator.
105         * 
106         * @param kemid
107         * @param ipIndicator
108         * @return a list of tax lots that meet the criteria
109         */
110        public List<HoldingTaxLot> getAllTaxLotsByKemIdAdndIPIndicator(String kemid, String ipIndicator) {
111            Map<String, String> criteria = new HashMap<String, String>();
112    
113            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_KEMID, kemid);
114            criteria.put(EndowPropertyConstants.HOLDING_TAX_LOT_INCOME_PRINCIPAL_INDICATOR, ipIndicator);
115    
116            return (List<HoldingTaxLot>) businessObjectService.findMatching(HoldingTaxLot.class, criteria);
117        }
118    
119        /**
120         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLotsWithPositiveUnits(java.lang.String,
121         *      java.lang.String, java.lang.String, java.lang.String)
122         */
123        public List<HoldingTaxLot> getAllTaxLotsWithPositiveUnits(String kemid, String securityId, String registrationCode, String ipIndicator) {
124            return (List<HoldingTaxLot>) holdingTaxLotDao.getAllTaxLotsWithPositiveUnits(kemid, securityId, registrationCode, ipIndicator);
125        }
126    
127        /**
128         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLotsWithPositiveCost(java.lang.String,
129         *      java.lang.String, java.lang.String, java.lang.String)
130         */
131        public List<HoldingTaxLot> getAllTaxLotsWithPositiveCost(String kemid, String securityId, String registrationCode, String ipIndicator) {
132            return (List<HoldingTaxLot>) holdingTaxLotDao.getAllTaxLotsWithPositiveCost(kemid, securityId, registrationCode, ipIndicator);
133        }
134    
135        /**
136         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getClassCodeType(String) Gets class code type based on
137         *      securityId. Based on security ID, you search END_SEC_T Table to get END_SEC_T:SEC_CLS_CD, then, based on class code, you
138         *      search END_CLS_CD_T, to get END_CLS_CD_T:CLS_CD_TYP
139         * @param id
140         * @return class code type
141         */
142        public String getClassCodeType(String securityId) {
143            String classCodeType = null;
144    
145            Security security = securityService.getByPrimaryKey(securityId);
146    
147            if (ObjectUtils.isNull(security)) {
148                throw new RuntimeException("Object Null: Unable to get Security Object for Security Id: " + securityId);
149            }
150    
151            ClassCode classCode = classCodeService.getByPrimaryKey(security.getSecurityClassCode());
152    
153            return classCode.getClassCodeType();
154        }
155    
156        /**
157         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getMarketValueForCashEquivalentsForAvailableIncomeCash()
158         *      The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of Cash Equivalents (C), and with the
159         *      HLDG_IP_IND equal to I.
160         * @return marketValue
161         */
162        public BigDecimal getMarketValueForCashEquivalentsForAvailableIncomeCash(String kemId) {
163            BigDecimal marketValue = BigDecimal.ZERO;
164    
165            List<HoldingTaxLot> holdingTaxLots = getAllTaxLotsByKemIdAdndIPIndicator(kemId, EndowConstants.IncomePrincipalIndicator.INCOME);
166            for (HoldingTaxLot holdingTaxLot : holdingTaxLots) {
167                // using sec_cd, get the class type code....
168                if (getClassCodeType(holdingTaxLot.getSecurityId()).equalsIgnoreCase(EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS)) {
169                    marketValue = marketValue.add(holdingTaxLot.getMarketValue());
170                }
171            }
172    
173            return marketValue;
174        }
175    
176        /**
177         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getMarketValueForPooledInvestmentForAvailableIncomeCash()
178         *      The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of Pooled Investment (P) and with the
179         *      HLDG_IP_IND equal to I times the value in the Available Cash Percent institutional parameter (accounts for only a
180         *      percentage of the market value allowing for pricing changes).
181         * @return marketValue
182         */
183        public BigDecimal getMarketValueForPooledInvestmentForAvailableIncomeCash(String kemId) {
184            BigDecimal marketValue = BigDecimal.ZERO;
185    
186            BigDecimal availableCashPercent = kEMService.getAvailableCashPercent();
187    
188            List<HoldingTaxLot> holdingTaxLots = getAllTaxLotsByKemIdAdndIPIndicator(kemId, EndowConstants.IncomePrincipalIndicator.INCOME);
189            for (HoldingTaxLot holdingTaxLot : holdingTaxLots) {
190                // using sec_cd, get the class type code and if class code type = POOLED_INVESTMENT then multiply the market value with
191                // percent
192                if (getClassCodeType(holdingTaxLot.getSecurityId()).equalsIgnoreCase(EndowConstants.ClassCodeTypes.POOLED_INVESTMENT)) {
193                    marketValue = marketValue.add(KEMCalculationRoundingHelper.multiply(holdingTaxLot.getMarketValue(), availableCashPercent, EndowConstants.Scale.SECURITY_MARKET_VALUE));
194                }
195            }
196    
197            return marketValue;
198        }
199    
200    
201        /**
202         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getMarketValueForCashEquivalentsForAvailablePrincipalCash()
203         *      The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of Cash Equivalents (C), and with the
204         *      HLDG_IP_IND equal to P.
205         * @return marketValue
206         */
207        public BigDecimal getMarketValueForCashEquivalentsForAvailablePrincipalCash(String kemId) {
208            BigDecimal marketValue = BigDecimal.ZERO;
209    
210            List<HoldingTaxLot> holdingTaxLots = getAllTaxLotsByKemIdAdndIPIndicator(kemId, EndowConstants.IncomePrincipalIndicator.PRINCIPAL);
211            for (HoldingTaxLot holdingTaxLot : holdingTaxLots) {
212                // using sec_cd, get the class type code....
213                if (getClassCodeType(holdingTaxLot.getSecurityId()).equalsIgnoreCase(EndowConstants.ClassCodeTypes.CASH_EQUIVALENTS)) {
214                    marketValue = marketValue.add(holdingTaxLot.getMarketValue());
215                }
216            }
217    
218            return marketValue;
219    
220        }
221    
222        /**
223         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getMarketValueForPooledInvestmentForAvailablePrincipalCash()
224         *      The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of Pooled Investment (P) and with the
225         *      HLDG_IP_IND equal to I times the value in the Available Cash Percent institutional parameter (accounts for only a
226         *      percentage of the market value allowing for pricing changes).
227         * @return marketValue
228         */
229        public BigDecimal getMarketValueForPooledInvestmentForAvailablePrincipalCash(String kemId) {
230            BigDecimal marketValue = BigDecimal.ZERO;
231    
232            BigDecimal availableCashPercent = kEMService.getAvailableCashPercent();
233    
234            List<HoldingTaxLot> holdingTaxLots = getAllTaxLotsByKemIdAdndIPIndicator(kemId, EndowConstants.IncomePrincipalIndicator.PRINCIPAL);
235            for (HoldingTaxLot holdingTaxLot : holdingTaxLots) {
236                // using sec_cd, get the class type code and if class code type = POOLED_INVESTMENT then multiply the market value with
237                // percent
238                if (getClassCodeType(holdingTaxLot.getSecurityId()).equalsIgnoreCase(EndowConstants.ClassCodeTypes.POOLED_INVESTMENT)) {
239                    marketValue = marketValue.add(KEMCalculationRoundingHelper.multiply(holdingTaxLot.getMarketValue(), availableCashPercent, EndowConstants.Scale.SECURITY_MARKET_VALUE));
240                }
241            }
242    
243            return marketValue;
244        }
245    
246        /**
247         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getAllTaxLotsWithAccruedIncomeGreaterThanZeroPerSecurity(java.lang.String)
248         */
249        public List<HoldingTaxLot> getAllTaxLotsWithAccruedIncomeGreaterThanZeroPerSecurity(String securityId) {
250    
251            return holdingTaxLotDao.getTaxLotsWithAccruedIncomeGreaterThanZeroPerSecurity(securityId);
252    
253        }
254    
255        /**
256         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#getTaxLotsPerSecurityIDWithUnitsGreaterThanZero(java.lang.String)
257         */
258        public List<HoldingTaxLot> getTaxLotsPerSecurityIDWithUnitsGreaterThanZero(String securityId) {
259            return holdingTaxLotDao.getTaxLotsPerSecurityIDWithUnitsGreaterThanZero(securityId);
260        }
261    
262        /**
263         * @see org.kuali.kfs.module.endow.document.service.HoldingTaxLotService#removeAllHoldingTaxLots()
264         */
265        public boolean removeAllHoldingTaxLots() {
266            boolean success = true;
267            
268            List<HoldingTaxLot> allTaxLots = getAllTaxLots();
269            for (HoldingTaxLot holdingTaxLot : allTaxLots) {
270                businessObjectService.delete(holdingTaxLot);
271            }
272            
273            return success;
274        }
275        
276        /**
277         * Gets the businessObjectService.
278         * 
279         * @return businessObjectService
280         */
281        protected BusinessObjectService getBusinessObjectService() {
282            return businessObjectService;
283        }
284    
285        /**
286         * Sets the businessObjectService.
287         * 
288         * @param businessObjectService
289         */
290        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
291            this.businessObjectService = businessObjectService;
292        }
293    
294        /**
295         * Gets the holdingTaxLotDao.
296         * 
297         * @return holdingTaxLotDao
298         */
299        protected HoldingTaxLotDao getHoldingTaxLotDao() {
300            return holdingTaxLotDao;
301        }
302    
303        /**
304         * Sets the holdingTaxLotDao.
305         * 
306         * @param holdingTaxLotDao
307         */
308        public void setHoldingTaxLotDao(HoldingTaxLotDao holdingTaxLotDao) {
309            this.holdingTaxLotDao = holdingTaxLotDao;
310        }
311    
312        /**
313         * Gets the securityService.
314         * 
315         * @return securityService
316         */
317        protected SecurityService getSecurityService() {
318            return securityService;
319        }
320    
321        /**
322         * Sets the securityService.
323         * 
324         * @param securityService
325         */
326        public void setSecurityService(SecurityService securityService) {
327            this.securityService = securityService;
328        }
329    
330        /**
331         * Gets the classCodeService.
332         * 
333         * @return classCodeService
334         */
335        protected ClassCodeService getClassCodeService() {
336            return classCodeService;
337        }
338    
339        /**
340         * Sets the classCodeService.
341         * 
342         * @param classCodeService
343         */
344        public void setClassCodeService(ClassCodeService classCodeService) {
345            this.classCodeService = classCodeService;
346        }
347    
348        /**
349         * gets the kEMService.
350         * 
351         * @param kEMService
352         */
353        protected KEMService getkEMService() {
354            return kEMService;
355        }
356    
357        /**
358         * Sets the kEMService.
359         * 
360         * @param kEMService
361         */
362        public void setkEMService(KEMService kEMService) {
363            this.kEMService = kEMService;
364        }
365    
366    }