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 }