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.kuali.kfs.gl.Constant; 025 import org.kuali.kfs.gl.OJBUtility; 026 import org.kuali.kfs.gl.batch.service.BalanceCalculator; 027 import org.kuali.kfs.gl.businessobject.Balance; 028 import org.kuali.kfs.gl.businessobject.TransientBalanceInquiryAttributes; 029 import org.kuali.kfs.gl.businessobject.inquiry.BalanceInquirableImpl; 030 import org.kuali.kfs.gl.service.BalanceService; 031 import org.kuali.kfs.sys.KFSConstants; 032 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 033 import org.kuali.rice.kns.bo.BusinessObject; 034 import org.kuali.rice.kns.lookup.HtmlData; 035 import org.kuali.rice.kns.util.KualiDecimal; 036 037 /** 038 * An extension of KualiLookupableImpl to support balance lookups 039 */ 040 public class BalanceLookupableHelperServiceImpl extends AbstractGeneralLedgerLookupableHelperServiceImpl { 041 private BalanceCalculator postBalance; 042 private BalanceService balanceService; 043 private Map fieldValues; 044 045 /** 046 * Returns the url for any drill down links within the lookup 047 * @param bo the business object with a property being drilled down on 048 * @param propertyName the name of the property being drilled down on 049 * @return a String with the URL of the property 050 * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String) 051 */ 052 @Override 053 public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) { 054 return (new BalanceInquirableImpl()).getInquiryUrl(bo, propertyName); 055 } 056 057 /** 058 * Generates the list of search results for this inquiry 059 * @param fieldValues the field values of the query to carry out 060 * @return List the search results returned by the lookup 061 * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map) 062 */ 063 @Override 064 public List getSearchResults(Map fieldValues) { 065 setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION)); 066 setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY)); 067 068 // get the pending entry option. This method must be prior to the get search results 069 String pendingEntryOption = this.getSelectedPendingEntryOption(fieldValues); 070 071 // test if the consolidation option is selected or not 072 boolean isConsolidated = isConsolidationSelected(fieldValues); 073 074 // get Amount View Option and determine if the results has to be accumulated 075 String amountViewOption = getSelectedAmountViewOption(fieldValues); 076 boolean isAccumulated = amountViewOption.equals(Constant.ACCUMULATE); 077 078 // get the search result collection 079 Iterator balanceIterator = balanceService.findBalance(fieldValues, isConsolidated); 080 Collection searchResultsCollection = this.buildBalanceCollection(balanceIterator, isConsolidated, pendingEntryOption); 081 082 // update search results according to the selected pending entry option 083 updateByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, isConsolidated, false); 084 085 // perform the accumulation of the amounts 086 this.accumulate(searchResultsCollection, isAccumulated); 087 088 // get the actual size of all qualified search results 089 Integer recordCount = balanceService.getBalanceRecordCount(fieldValues, isConsolidated); 090 Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, fieldValues, new Balance()); 091 092 return this.buildSearchResultList(searchResultsCollection, actualSize); 093 } 094 095 /** 096 * This method builds the balance collection based on the input iterator 097 * 098 * @param iterator the iterator of search results of balance 099 * @param isConsolidated determine if the consolidated result is desired 100 * @param pendingEntryOption the given pending entry option that can be no, approved or all 101 * @return the balance collection 102 */ 103 private Collection buildBalanceCollection(Iterator iterator, boolean isConsolidated, String pendingEntryOption) { 104 Collection balanceCollection = null; 105 106 if (isConsolidated) { 107 balanceCollection = buildConsolidatedBalanceCollection(iterator, pendingEntryOption); 108 } 109 else { 110 balanceCollection = buildDetailedBalanceCollection(iterator, pendingEntryOption); 111 } 112 return balanceCollection; 113 } 114 115 /** 116 * This method builds the balance collection with consolidation option from an iterator 117 * 118 * @param iterator th iterator of balance results 119 * @param pendingEntryOption the selected pending entry option 120 * @return the consolidated balance collection 121 */ 122 private Collection buildConsolidatedBalanceCollection(Iterator iterator, String pendingEntryOption) { 123 Collection balanceCollection = new ArrayList(); 124 125 while (iterator.hasNext()) { 126 Object collectionEntry = iterator.next(); 127 128 if (collectionEntry.getClass().isArray()) { 129 int i = 0; 130 Object[] array = (Object[]) collectionEntry; 131 Balance balance = new Balance(); 132 133 balance.setUniversityFiscalYear(new Integer(array[i++].toString())); 134 balance.setChartOfAccountsCode(array[i++].toString()); 135 balance.setAccountNumber(array[i++].toString()); 136 137 String subAccountNumber = Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER; 138 balance.setSubAccountNumber(subAccountNumber); 139 140 balance.setBalanceTypeCode(array[i++].toString()); 141 balance.setObjectCode(array[i++].toString()); 142 143 balance.setSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE); 144 balance.setObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE); 145 146 balance.setAccountLineAnnualBalanceAmount(new KualiDecimal(array[i++].toString())); 147 balance.setBeginningBalanceLineAmount(new KualiDecimal(array[i++].toString())); 148 balance.setContractsGrantsBeginningBalanceAmount(new KualiDecimal(array[i++].toString())); 149 150 balance.setMonth1Amount(new KualiDecimal(array[i++].toString())); 151 balance.setMonth2Amount(new KualiDecimal(array[i++].toString())); 152 balance.setMonth3Amount(new KualiDecimal(array[i++].toString())); 153 balance.setMonth4Amount(new KualiDecimal(array[i++].toString())); 154 balance.setMonth5Amount(new KualiDecimal(array[i++].toString())); 155 balance.setMonth6Amount(new KualiDecimal(array[i++].toString())); 156 balance.setMonth7Amount(new KualiDecimal(array[i++].toString())); 157 balance.setMonth8Amount(new KualiDecimal(array[i++].toString())); 158 balance.setMonth9Amount(new KualiDecimal(array[i++].toString())); 159 160 balance.setMonth10Amount(new KualiDecimal(array[i++].toString())); 161 balance.setMonth11Amount(new KualiDecimal(array[i++].toString())); 162 balance.setMonth12Amount(new KualiDecimal(array[i++].toString())); 163 balance.setMonth13Amount(new KualiDecimal(array[i].toString())); 164 165 balance.setDummyBusinessObject(new TransientBalanceInquiryAttributes()); 166 balance.getDummyBusinessObject().setPendingEntryOption(pendingEntryOption); 167 168 balanceCollection.add(balance); 169 } 170 } 171 return balanceCollection; 172 } 173 174 /** 175 * This method builds the balance collection with detail option from an iterator 176 * 177 * @param iterator the balance iterator 178 * @param pendingEntryOption the selected pending entry option 179 * @return the detailed balance collection 180 */ 181 private Collection buildDetailedBalanceCollection(Iterator iterator, String pendingEntryOption) { 182 Collection balanceCollection = new ArrayList(); 183 184 while (iterator.hasNext()) { 185 Balance balance = (Balance) (iterator.next()); 186 187 balance.setDummyBusinessObject(new TransientBalanceInquiryAttributes()); 188 balance.getDummyBusinessObject().setPendingEntryOption(pendingEntryOption); 189 190 balanceCollection.add(balance); 191 } 192 return balanceCollection; 193 } 194 195 /** 196 * This method updates the balance collection with accumulated amounts if required (isAccumulated is true) 197 * 198 * @param balanceCollection the balance collection to be updated 199 * @param isAccumulated determine if the accumulated result is desired 200 */ 201 private void accumulate(Collection balanceCollection, boolean isAccumulated) { 202 203 if (isAccumulated) { 204 for (Iterator iterator = balanceCollection.iterator(); iterator.hasNext();) { 205 Balance balance = (Balance) (iterator.next()); 206 accumulateByBalance(balance, isAccumulated); 207 } 208 } 209 } 210 211 /** 212 * This method computes the accumulate amount of the given balance and updates its fields 213 * 214 * @param balance the given balance object 215 * @param isAccumulated determine if the accumulated result is desired 216 */ 217 private void accumulateByBalance(Balance balance, boolean isAccumulated) { 218 219 KualiDecimal annualAmount = balance.getAccountLineAnnualBalanceAmount(); 220 KualiDecimal beginningAmount = balance.getBeginningBalanceLineAmount(); 221 KualiDecimal CGBeginningAmount = balance.getContractsGrantsBeginningBalanceAmount(); 222 223 KualiDecimal month0Amount = beginningAmount.add(CGBeginningAmount); 224 KualiDecimal month1Amount = balance.getMonth1Amount(); 225 month1Amount = accumulateAmount(month1Amount, month0Amount, isAccumulated); 226 balance.setMonth1Amount(month1Amount); 227 228 KualiDecimal month2Amount = balance.getMonth2Amount(); 229 month2Amount = accumulateAmount(month2Amount, month1Amount, isAccumulated); 230 balance.setMonth2Amount(month2Amount); 231 232 KualiDecimal month3Amount = balance.getMonth3Amount(); 233 month3Amount = accumulateAmount(month3Amount, month2Amount, isAccumulated); 234 balance.setMonth3Amount(month3Amount); 235 236 KualiDecimal month4Amount = balance.getMonth4Amount(); 237 month4Amount = accumulateAmount(month4Amount, month3Amount, isAccumulated); 238 balance.setMonth4Amount(month4Amount); 239 240 KualiDecimal month5Amount = balance.getMonth5Amount(); 241 month5Amount = accumulateAmount(month5Amount, month4Amount, isAccumulated); 242 balance.setMonth5Amount(month5Amount); 243 244 KualiDecimal month6Amount = balance.getMonth6Amount(); 245 month6Amount = accumulateAmount(month6Amount, month5Amount, isAccumulated); 246 balance.setMonth6Amount(month6Amount); 247 248 KualiDecimal month7Amount = balance.getMonth7Amount(); 249 month7Amount = accumulateAmount(month7Amount, month6Amount, isAccumulated); 250 balance.setMonth7Amount(month7Amount); 251 252 KualiDecimal month8Amount = balance.getMonth8Amount(); 253 month8Amount = accumulateAmount(month8Amount, month7Amount, isAccumulated); 254 balance.setMonth8Amount(month8Amount); 255 256 KualiDecimal month9Amount = balance.getMonth9Amount(); 257 month9Amount = accumulateAmount(month9Amount, month8Amount, isAccumulated); 258 balance.setMonth9Amount(month9Amount); 259 260 KualiDecimal month10Amount = balance.getMonth10Amount(); 261 month10Amount = accumulateAmount(month10Amount, month9Amount, isAccumulated); 262 balance.setMonth10Amount(month10Amount); 263 264 KualiDecimal month11Amount = balance.getMonth11Amount(); 265 month11Amount = accumulateAmount(month11Amount, month10Amount, isAccumulated); 266 balance.setMonth11Amount(month11Amount); 267 268 KualiDecimal month12Amount = balance.getMonth12Amount(); 269 month12Amount = accumulateAmount(month12Amount, month11Amount, isAccumulated); 270 balance.setMonth12Amount(month12Amount); 271 272 KualiDecimal month13Amount = balance.getMonth13Amount(); 273 month13Amount = accumulateAmount(month13Amount, month12Amount, isAccumulated); 274 balance.setMonth13Amount(month13Amount); 275 } 276 277 /** 278 * This method converts the amount from String and adds it with the input addend 279 * 280 * @param stringAugend a String-type augend 281 * @param addend an addend 282 * @param isAccumulated determine if the accumulated result is desired 283 * @return the accumulated amount if accumulate option is selected; otherwise, the input amount itself 284 */ 285 private KualiDecimal accumulateAmount(Object stringAugend, KualiDecimal addend, boolean isAccumulated) { 286 287 KualiDecimal augend = new KualiDecimal(stringAugend.toString()); 288 if (isAccumulated) { 289 augend = augend.add(addend); 290 } 291 return augend; 292 } 293 294 /** 295 * Updates pending entries before their results are included in the lookup results 296 * 297 * @param entryCollection a collection of balance entries 298 * @param fieldValues the map containing the search fields and values 299 * @param isApproved flag whether the approved entries or all entries will be processed 300 * @param isConsolidated flag whether the results are consolidated or not 301 * @param isCostShareExcluded flag whether the user selects to see the results with cost share subaccount 302 * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableImpl#updateEntryCollection(java.util.Collection, java.util.Map, 303 * boolean, boolean, boolean) 304 */ 305 public void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) { 306 307 // convert the field names of balance object into corresponding ones of pending entry object 308 Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues); 309 310 // go through the pending entries to update the balance collection 311 Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForBalance(pendingEntryFieldValues, isApproved); 312 while (pendingEntryIterator.hasNext()) { 313 GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next(); 314 315 // if consolidated, change the following fields into the default values for consolidation 316 if (isConsolidated) { 317 pendingEntry.setSubAccountNumber(Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER); 318 pendingEntry.setFinancialSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE); 319 pendingEntry.setFinancialObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE); 320 } 321 322 Balance balance = postBalance.findBalance(entryCollection, pendingEntry); 323 324 String pendingEntryOption = isApproved ? Constant.APPROVED_PENDING_ENTRY : Constant.ALL_PENDING_ENTRY; 325 balance.setDummyBusinessObject(new TransientBalanceInquiryAttributes()); 326 balance.getDummyBusinessObject().setPendingEntryOption(pendingEntryOption); 327 328 postBalance.updateBalance(pendingEntry, balance); 329 } 330 } 331 332 /** 333 * Sets the postBalance attribute value. 334 * 335 * @param postBalance The postBalance to set. 336 */ 337 public void setPostBalance(BalanceCalculator postBalance) { 338 this.postBalance = postBalance; 339 } 340 341 /** 342 * Sets the balanceService attribute value. 343 * 344 * @param balanceService The balanceService to set. 345 */ 346 public void setBalanceService(BalanceService balanceService) { 347 this.balanceService = balanceService; 348 } 349 350 }