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.batch.service.impl;
017
018 import java.math.BigDecimal;
019 import java.util.Collection;
020
021 import org.kuali.kfs.module.endow.EndowParameterKeyConstants;
022 import org.kuali.kfs.module.endow.batch.AvailableCashUpdateStep;
023 import org.kuali.kfs.module.endow.batch.service.AvailableCashUpdateService;
024 import org.kuali.kfs.module.endow.batch.service.KEMIDCurrentAvailableBalanceService;
025 import org.kuali.kfs.module.endow.businessobject.KEMID;
026 import org.kuali.kfs.module.endow.businessobject.KEMIDCurrentAvailableBalance;
027 import org.kuali.kfs.module.endow.businessobject.KemidCurrentCash;
028 import org.kuali.kfs.module.endow.document.service.HoldingTaxLotService;
029 import org.kuali.kfs.module.endow.document.service.KEMIDService;
030 import org.kuali.kfs.module.endow.document.service.KemidCurrentCashService;
031 import org.kuali.rice.kns.service.ParameterService;
032 import org.kuali.rice.kns.util.Guid;
033 import org.kuali.rice.kns.util.ObjectUtils;
034 import org.springframework.transaction.annotation.Transactional;
035
036 /**
037 * This class implements the AvailableCashUpdateService batch job.
038 */
039 @Transactional
040 public class AvailableCashUpdateServiceImpl implements AvailableCashUpdateService {
041 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AvailableCashUpdateServiceImpl.class);
042
043 protected ParameterService parameterService;
044 protected KemidCurrentCashService kemidCurrentCashService;
045 protected HoldingTaxLotService holdingTaxLotService;
046 protected KEMIDService kEMIDService;
047 protected KEMIDCurrentAvailableBalanceService kEMIDCurrentAvailableBalanceService;
048 /**
049 * Constructs a AvailableCashUpdateServiceImpl instance
050 */
051 public AvailableCashUpdateServiceImpl() {
052
053 }
054
055 /**
056 * This process will generate records at the end of each processing cycle to summarize the
057 * available spendable funds for every KEMID that is not closed.
058 */
059 public boolean summarizeAvailableSpendableFunds() {
060 boolean success = true;
061
062 if (systemParametersForSummarizeAvailableSpendableFundsJobExist()) {
063 //Step 1: remove all the records from END_AVAIL_CSH_T table
064 kEMIDCurrentAvailableBalanceService.clearAllAvailableCash();
065
066 //Step 2: Retrieve all KEMID records where CLOSED_IND set to N
067 Collection<KEMID> kemIdRecords = kEMIDService.getAllKemIdWithClosedIndicatorNo();
068 //process the records in the collection
069 for (KEMID kemIdRecord : kemIdRecords) {
070 KEMIDCurrentAvailableBalance kEMIDCurrentAvailableBalance = new KEMIDCurrentAvailableBalance();
071 String kemId = kemIdRecord.getKemid();
072 kEMIDCurrentAvailableBalance.setKemid(kemId);
073 LOG.info("Calculate sum for available income cash and available principal cash for the kemid: " + kemId);
074 kEMIDCurrentAvailableBalance.setAvailableIncomeCash(getAvailableIncomeCash(kemId));
075 kEMIDCurrentAvailableBalance.setAvailablePrincipalCash(getAvailablePrincipalCash(kemId, kemIdRecord.getPrincipalRestrictionCode()));
076 kEMIDCurrentAvailableBalance.setAvailableTotalCash(kEMIDCurrentAvailableBalance.getAvailableIncomeCash().add(kEMIDCurrentAvailableBalance.getAvailablePrincipalCash()));
077 kEMIDCurrentAvailableBalance.setObjectId(new Guid().toString());
078 kEMIDCurrentAvailableBalance.setVersionNumber(1L);
079 kEMIDCurrentAvailableBalanceService.InsertAvailableCash(kEMIDCurrentAvailableBalance);
080 }
081 }
082
083 LOG.info("Processed all KEMID records. Summarized available spendable funds.");
084
085 return success;
086 }
087
088 /**
089 * This method checks if the System parameters have been set up for this batch job.
090 * @result return true if the system parameters exist, else false
091 */
092 protected boolean systemParametersForSummarizeAvailableSpendableFundsJobExist() {
093 LOG.info("systemParametersForSummarizeAvailableSpendableFundsJobExist() started.");
094
095 boolean systemParameterExists = true;
096
097 // check to make sure the system parameter has been setup...
098 if (!getParameterService().parameterExists(AvailableCashUpdateStep.class, EndowParameterKeyConstants.AvailableCashUpdateConstants.AVAILABLE_CASH_PERCENT)) {
099 LOG.warn("AVAILABLE_CASH_PERCENT System parameter does not exist in the parameters list. The job can not continue without this parameter");
100 return false;
101 }
102
103 return systemParameterExists;
104 }
105
106 /**
107 * Method to calculate sum of available cash Income Cash
108 * 1. END_CRNT_CSH_T: CRNT_INC_CSH for the KEMID
109 * 2. The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of
110 * Cash Equivalents (C), and with the HLDG_IP_IND equal to I.
111 * 3. The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of
112 * Pooled Investment (P) and with the HLDG_IP_IND equal to I times the value in the
113 * Available Cash Percent institutional parameter (accounts for only a percentage of the market
114 * value allowing for pricing changes).
115 * @param kemId
116 * @return availableIncomeCash
117 */
118 protected BigDecimal getAvailableIncomeCash(String kemId) {
119 BigDecimal availableIncomeCash = BigDecimal.ZERO;
120
121 KemidCurrentCash kemidCurrentCash = kemidCurrentCashService.getByPrimaryKey(kemId);
122 if (ObjectUtils.isNotNull(kemidCurrentCash)) {
123 availableIncomeCash = availableIncomeCash.add(kemidCurrentCash.getCurrentIncomeCash().bigDecimalValue());
124 }
125
126 //get market value of the KEMID with class code type = C and IP indicator = I
127 availableIncomeCash = availableIncomeCash.add(holdingTaxLotService.getMarketValueForCashEquivalentsForAvailableIncomeCash(kemId));
128
129 //get market value of the KEMID with class code type = P and IP indicator = I
130 availableIncomeCash = availableIncomeCash.add(holdingTaxLotService.getMarketValueForPooledInvestmentForAvailableIncomeCash(kemId));
131
132 return availableIncomeCash;
133 }
134
135 /**
136 * If the END_KEMID_T record has a TYP_PRIN_RESTR CD where END_TYP_RESTR_CD_T: PERM is
137 * equal to Y (Yes), the principal is Permanently Restricted and AVAIL_PRIN_CSH is zero (0.00).
138 * Otherwise Principal Available Cash is the sum of all of the following :
139 * END_CRNT_CSH: CRNT_PRIN_CSH
140 * The Market Value of the END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of Cash Equivalents (C)
141 * and with the HLDG_IP_IND equal to P.
142 * The Market Value of the KEMID END_HLDG_TAX_LOT_T records with a CLS_CD_TYP of
143 * Pooled Investment (P) and with the HLDG_IP_IND equal to P times the value in the
144 * Available Cash Percent institutional parameter (accounts for only a percentage of
145 * the market value allowing for pricing changes)
146 *
147 * @param kemId, typeRestrictionCode
148 * @return availableIncomeCash
149 */
150 protected BigDecimal getAvailablePrincipalCash(String kemId, String typePrincipalRestrictedCode) {
151 BigDecimal availablePrincipalCash = BigDecimal.ZERO;
152
153 if (kEMIDService.isTrueEndowment(kemId)) {
154 return availablePrincipalCash;
155 }
156
157 KemidCurrentCash kemidCurrentCash = kemidCurrentCashService.getByPrimaryKey(kemId);
158
159 if (ObjectUtils.isNotNull(kemidCurrentCash)) {
160 availablePrincipalCash = availablePrincipalCash.add(kemidCurrentCash.getCurrentPrincipalCash().bigDecimalValue());
161 }
162
163 //get market value of the KEMID with class code type = C and IP indicator = P
164 availablePrincipalCash = availablePrincipalCash.add(holdingTaxLotService.getMarketValueForCashEquivalentsForAvailablePrincipalCash(kemId));
165
166 //get market value of the KEMID with class code type = P and IP indicator = P
167 availablePrincipalCash = availablePrincipalCash.add(holdingTaxLotService.getMarketValueForPooledInvestmentForAvailablePrincipalCash(kemId));
168
169 return availablePrincipalCash;
170 }
171
172 /**
173 * Gets the parameterService attribute.
174 *
175 * @return Returns the parameterService.
176 */
177 protected ParameterService getParameterService() {
178 return parameterService;
179 }
180
181 /**
182 * Sets the parameterService attribute value.
183 *
184 * @param parameterService The parameterService to set.
185 */
186 public void setParameterService(ParameterService parameterService) {
187 this.parameterService = parameterService;
188 }
189
190 /**
191 * gets the kemidCurrentCashService
192 *
193 * @param kemidCurrentCashService The kemidCurrentCashService to get.
194 */
195 protected KemidCurrentCashService getKemidCurrentCashOpenRecordsService() {
196 return kemidCurrentCashService;
197 }
198
199 /**
200 * Sets the kemidCurrentCashService
201 *
202 * @param kemidCurrentCashService The kemidCurrentCashService to set.
203 */
204 public void setKemidCurrentCashService(KemidCurrentCashService kemidCurrentCashService) {
205 this.kemidCurrentCashService = kemidCurrentCashService;
206 }
207
208 /**
209 * gets the holdingTaxLotService
210 *
211 * @param holdingTaxLotService The holdingTaxLotService to get.
212 */
213 protected HoldingTaxLotService getHoldingTaxLotService() {
214 return holdingTaxLotService;
215 }
216
217 /**
218 * Sets the holdingTaxLotService
219 *
220 * @param holdingTaxLotService The holdingTaxLotService to set.
221 */
222 public void setHoldingTaxLotService(HoldingTaxLotService holdingTaxLotService) {
223 this.holdingTaxLotService = holdingTaxLotService;
224 }
225
226 /**
227 * gets the kEMIDService
228 *
229 * @param kEMIDService The kEMIDService to get.
230 */
231 protected KEMIDService getkEMIDService() {
232 return kEMIDService;
233 }
234
235 /**
236 * gets the kEMIDService
237 *
238 * @param kEMIDService The kEMIDService to get.
239 */
240 public void setkEMIDService(KEMIDService kEMIDService) {
241 this.kEMIDService = kEMIDService;
242 }
243
244 /**
245 * Gets the kEMIDCurrentAvailableBalanceService attribute.
246 * @return Returns the kEMIDCurrentAvailableBalanceService.
247 */
248 protected KEMIDCurrentAvailableBalanceService getkEMIDCurrentAvailableBalanceService() {
249 return kEMIDCurrentAvailableBalanceService;
250 }
251
252 /**
253 * Sets the kEMIDCurrentAvailableBalanceService attribute value.
254 * @param kEMIDCurrentAvailableBalanceService The kEMIDCurrentAvailableBalanceService to set.
255 */
256 public void setkEMIDCurrentAvailableBalanceService(KEMIDCurrentAvailableBalanceService kEMIDCurrentAvailableBalanceService) {
257 this.kEMIDCurrentAvailableBalanceService = kEMIDCurrentAvailableBalanceService;
258 }
259 }