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.gl.businessobject.lookup; 017 018 import java.util.ArrayList; 019 import java.util.Collection; 020 import java.util.Iterator; 021 import java.util.List; 022 import java.util.Map; 023 024 import org.apache.commons.lang.StringUtils; 025 import org.kuali.kfs.coa.businessobject.Account; 026 import org.kuali.kfs.gl.Constant; 027 import org.kuali.kfs.gl.OJBUtility; 028 import org.kuali.kfs.gl.batch.service.BalanceCalculator; 029 import org.kuali.kfs.gl.businessobject.Balance; 030 import org.kuali.kfs.gl.businessobject.CashBalance; 031 import org.kuali.kfs.gl.businessobject.inquiry.CashBalanceInquirableImpl; 032 import org.kuali.kfs.gl.service.BalanceService; 033 import org.kuali.kfs.sys.KFSConstants; 034 import org.kuali.kfs.sys.KFSPropertyConstants; 035 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 036 import org.kuali.kfs.sys.businessobject.UniversityDate; 037 import org.kuali.kfs.sys.context.SpringContext; 038 import org.kuali.kfs.sys.service.UniversityDateService; 039 import org.kuali.rice.kns.bo.BusinessObject; 040 import org.kuali.rice.kns.lookup.HtmlData; 041 import org.kuali.rice.kns.util.KualiDecimal; 042 import org.kuali.rice.kns.util.ObjectUtils; 043 import org.kuali.rice.kns.web.ui.Field; 044 import org.kuali.rice.kns.web.ui.Row; 045 046 /** 047 * An extension of KualiLookupableImpl to support cash lookups 048 */ 049 public class CashBalanceLookupableHelperServiceImpl extends AbstractGeneralLedgerLookupableHelperServiceImpl { 050 private BalanceCalculator postBalance; 051 private BalanceService balanceService; 052 053 /** 054 * Returns the URL for inquiries on fields returned in the lookup 055 * @param bo the business object the field to inquiry on is in 056 * @param propertyName the name of the property that an inquiry url is being asked of 057 * @return the String of the url 058 * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String) 059 */ 060 @Override 061 public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) { 062 return (new CashBalanceInquirableImpl()).getInquiryUrl(bo, propertyName); 063 } 064 065 /** 066 * Generates a list of results for this inquiry 067 * @param fieldValues the field values that the user entered for this inquiry 068 * @return a List of results 069 * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map) 070 */ 071 @Override 072 public List getSearchResults(Map fieldValues) { 073 setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION)); 074 setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY)); 075 076 // get the pending entry option. This method must be prior to the get search results 077 String pendingEntryOption = getSelectedPendingEntryOption(fieldValues); 078 079 // get the consolidation option 080 boolean isConsolidated = isConsolidationSelected(fieldValues); 081 082 // get the search result collection 083 Iterator cashBalanceIterator = balanceService.findCashBalance(fieldValues, isConsolidated); 084 Collection searchResultsCollection = this.buildCashBalanceCollection(cashBalanceIterator, isConsolidated); 085 086 // update search results according to the selected pending entry option 087 updateByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, isConsolidated, false); 088 089 // get the actual size of all qualified search results 090 Integer recordCount = balanceService.getCashBalanceRecordCount(fieldValues, isConsolidated); 091 Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, fieldValues, new Balance()); 092 093 return this.buildSearchResultList(searchResultsCollection, actualSize); 094 } 095 096 /** 097 * This method builds the cash balance collection based on the input iterator 098 * 099 * @param iterator the iterator of search results of avaiable cash balance 100 * @return the cash balance collection 101 */ 102 private Collection buildCashBalanceCollection(Iterator iterator, boolean isConsolidated) { 103 Collection balanceCollection = new ArrayList(); 104 105 while (iterator.hasNext()) { 106 Object cashBalance = iterator.next(); 107 108 if (cashBalance.getClass().isArray()) { 109 int i = 0; 110 Object[] array = (Object[]) cashBalance; 111 Balance balance = new CashBalance(); 112 113 balance.setUniversityFiscalYear(new Integer(array[i++].toString())); 114 balance.setChartOfAccountsCode(array[i++].toString()); 115 balance.setAccountNumber(array[i++].toString()); 116 117 String subAccountNumber = isConsolidated ? Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER : array[i++].toString(); 118 balance.setSubAccountNumber(subAccountNumber); 119 120 balance.setBalanceTypeCode(array[i++].toString()); 121 balance.setObjectCode(array[i++].toString()); 122 123 String subObjectCode = isConsolidated ? Constant.CONSOLIDATED_SUB_OBJECT_CODE : array[i++].toString(); 124 balance.setSubObjectCode(subObjectCode); 125 126 String objectTypeCode = isConsolidated ? Constant.CONSOLIDATED_OBJECT_TYPE_CODE : array[i++].toString(); 127 balance.setObjectTypeCode(objectTypeCode); 128 129 KualiDecimal annualAmount = new KualiDecimal(array[i++].toString()); 130 balance.setAccountLineAnnualBalanceAmount(annualAmount); 131 132 KualiDecimal beginningAmount = new KualiDecimal(array[i++].toString()); 133 balance.setBeginningBalanceLineAmount(beginningAmount); 134 135 KualiDecimal CGBeginningAmount = new KualiDecimal(array[i].toString()); 136 balance.setContractsGrantsBeginningBalanceAmount(CGBeginningAmount); 137 138 KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance); 139 balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount); 140 141 balanceCollection.add(balance); 142 } 143 } 144 return balanceCollection; 145 } 146 147 /** 148 * Allows an updating of pending entry records before they are applied to the inquiry results 149 * 150 * @param entryCollection a collection of balance entries 151 * @param fieldValues the map containing the search fields and values 152 * @param isApproved flag whether the approved entries or all entries will be processed 153 * @param isConsolidated flag whether the results are consolidated or not 154 * @param isCostShareExcluded flag whether the user selects to see the results with cost share subaccount 155 * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableImpl#updateEntryCollection(java.util.Collection, java.util.Map, 156 * boolean, boolean, boolean) 157 */ 158 @Override 159 protected void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) { 160 161 // convert the field names of balance object into corresponding ones of pending entry object 162 Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues); 163 164 UniversityDate today = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate(); 165 String currentFiscalPeriodCode = today.getUniversityFiscalAccountingPeriod(); 166 Integer currentFiscalYear = today.getUniversityFiscalYear(); 167 168 // use the pending entry to update the input entry collection 169 Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForCashBalance(pendingEntryFieldValues, isApproved); 170 while (pendingEntryIterator.hasNext()) { 171 GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next(); 172 173 // Fix the fiscal period/year if they are null 174 // Don't want to use the GLPE service.fillInFiscalPeriodYear. It totally kills performance. 175 // generalLedgerPendingEntryService.fillInFiscalPeriodYear(pendingEntry); 176 177 if (pendingEntry.getUniversityFiscalYear() == null) { 178 pendingEntry.setUniversityFiscalYear(currentFiscalYear); 179 } 180 181 if (pendingEntry.getUniversityFiscalPeriodCode() == null) { 182 pendingEntry.setUniversityFiscalPeriodCode(currentFiscalPeriodCode); 183 } 184 185 // if consolidated, change the following fields into the default values for consolidation 186 if (isConsolidated) { 187 pendingEntry.setSubAccountNumber(Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER); 188 pendingEntry.setFinancialSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE); 189 pendingEntry.setFinancialObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE); 190 } 191 Balance balance = postBalance.findBalance(entryCollection, pendingEntry); 192 postBalance.updateBalance(pendingEntry, balance); 193 194 KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance); 195 balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount); 196 } 197 } 198 199 // calculate the total available cash amont of the given balance record 200 private KualiDecimal getTotalAvailableCashAmount(Balance balance) { 201 KualiDecimal annualAmount = balance.getAccountLineAnnualBalanceAmount(); 202 KualiDecimal beginningAmount = balance.getBeginningBalanceLineAmount(); 203 KualiDecimal CGBeginningAmount = balance.getContractsGrantsBeginningBalanceAmount(); 204 205 KualiDecimal totalAvailableAmount = annualAmount.add(beginningAmount); 206 totalAvailableAmount = totalAvailableAmount.add(CGBeginningAmount); 207 208 return totalAvailableAmount; 209 } 210 211 /** 212 * Sets the postBalance attribute value. 213 * 214 * @param postBalance The postBalance to set. 215 */ 216 public void setPostBalance(BalanceCalculator postBalance) { 217 this.postBalance = postBalance; 218 } 219 220 /** 221 * Sets the balanceService attribute value. 222 * 223 * @param balanceService The balanceService to set. 224 */ 225 public void setBalanceService(BalanceService balanceService) { 226 this.balanceService = balanceService; 227 } 228 229 @Override 230 public List<Row> getRows() { 231 // TODO Auto-generated method stub 232 List<Row> rows = super.getRows(); 233 234 //look for field and replace BO class 235 for (Iterator iter = rows.iterator(); iter.hasNext();) { 236 Row row = (Row) iter.next(); 237 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) { 238 Field field = (Field) iterator.next(); 239 240 if(ObjectUtils.isNotNull(field) && StringUtils.equalsIgnoreCase(field.getPropertyName(), KFSPropertyConstants.ACCOUNT_NUMBER)){ 241 field.setQuickFinderClassNameImpl(Account.class.getName()); 242 } 243 } 244 } 245 246 return rows; 247 } 248 249 }