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 }