View Javadoc
1   /*
2    * Copyright 2006 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.gl.businessobject.lookup;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.kuali.ole.coa.businessobject.Account;
26  import org.kuali.ole.gl.Constant;
27  import org.kuali.ole.gl.GeneralLedgerConstants;
28  import org.kuali.ole.gl.OJBUtility;
29  import org.kuali.ole.gl.batch.service.BalanceCalculator;
30  import org.kuali.ole.gl.businessobject.Balance;
31  import org.kuali.ole.gl.businessobject.CashBalance;
32  import org.kuali.ole.gl.businessobject.inquiry.CashBalanceInquirableImpl;
33  import org.kuali.ole.gl.service.BalanceService;
34  import org.kuali.ole.sys.OLEConstants;
35  import org.kuali.ole.sys.OLEPropertyConstants;
36  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
37  import org.kuali.ole.sys.businessobject.UniversityDate;
38  import org.kuali.ole.sys.context.SpringContext;
39  import org.kuali.ole.sys.service.UniversityDateService;
40  import org.kuali.rice.core.api.util.type.KualiDecimal;
41  import org.kuali.rice.kns.lookup.HtmlData;
42  import org.kuali.rice.kns.web.ui.Field;
43  import org.kuali.rice.kns.web.ui.Row;
44  import org.kuali.rice.krad.bo.BusinessObject;
45  import org.kuali.rice.krad.util.ObjectUtils;
46  
47  /**
48   * An extension of KualiLookupableImpl to support cash lookups
49   */
50  public class CashBalanceLookupableHelperServiceImpl extends AbstractGeneralLedgerLookupableHelperServiceImpl {
51      private BalanceCalculator postBalance;
52      private BalanceService balanceService;
53  
54      /**
55       * Returns the URL for inquiries on fields returned in the lookup
56       * 
57       * @param bo the business object the field to inquiry on is in
58       * @param propertyName the name of the property that an inquiry url is being asked of
59       * @return the String of the url
60       * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.krad.bo.BusinessObject, java.lang.String) KRAD
61       *      Conversion: Lookupable modifies the search results based on the fields consolidated. But all field definitions are in
62       *      data dictionary.
63       */
64      @Override
65      public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
66          return (new CashBalanceInquirableImpl()).getInquiryUrl(bo, propertyName);
67      }
68  
69      /**
70       * Generates a list of results for this inquiry
71       * 
72       * @param fieldValues the field values that the user entered for this inquiry
73       * @return a List of results
74       * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map)
75       */
76      @Override
77      public List getSearchResults(Map fieldValues) {
78          setBackLocation((String) fieldValues.get(OLEConstants.BACK_LOCATION));
79          setDocFormKey((String) fieldValues.get(OLEConstants.DOC_FORM_KEY));
80  
81          // get the pending entry option. This method must be prior to the get search results
82          String pendingEntryOption = getSelectedPendingEntryOption(fieldValues);
83  
84          
85          
86          // KFSMI-410: need to get this before getting isConsolidated because this value will be removed.
87          String consolidationOption = (String) fieldValues.get(GeneralLedgerConstants.DummyBusinessObject.CONSOLIDATION_OPTION);
88          // get the consolidation option
89          boolean isConsolidated = isConsolidationSelected(fieldValues);
90  
91          // KFSMI-410: added one more node for consolidationOption
92          if (consolidationOption.equals(Constant.EXCLUDE_SUBACCOUNTS)){
93              fieldValues.put(Constant.SUB_ACCOUNT_OPTION, OLEConstants.getDashSubAccountNumber());
94              isConsolidated = false;
95          } 
96          
97          // get the search result collection
98          Iterator cashBalanceIterator = balanceService.lookupCashBalance(fieldValues, isConsolidated);
99          Collection searchResultsCollection = this.buildCashBalanceCollection(cashBalanceIterator, isConsolidated);
100 
101         // update search results according to the selected pending entry option
102         updateByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, isConsolidated, false);
103 
104         // get the actual size of all qualified search results
105         Integer recordCount = balanceService.getCashBalanceRecordCount(fieldValues, isConsolidated);
106         Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, fieldValues, new Balance());
107 
108         return this.buildSearchResultList(searchResultsCollection, actualSize);
109     }
110 
111     /**
112      * This method builds the cash balance collection based on the input iterator
113      * 
114      * @param iterator the iterator of search results of avaiable cash balance
115      * @return the cash balance collection
116      */
117     private Collection buildCashBalanceCollection(Iterator iterator, boolean isConsolidated) {
118         Collection balanceCollection = new ArrayList();
119 
120         while (iterator.hasNext()) {
121             Object cashBalance = iterator.next();
122 
123             if (cashBalance.getClass().isArray()) {
124                 int i = 0;
125                 Object[] array = (Object[]) cashBalance;
126                 Balance balance = new CashBalance();
127 
128                 balance.setUniversityFiscalYear(new Integer(array[i++].toString()));
129                 balance.setChartOfAccountsCode(array[i++].toString());
130                 balance.setAccountNumber(array[i++].toString());
131 
132                 String subAccountNumber = isConsolidated ? Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER : array[i++].toString();
133                 balance.setSubAccountNumber(subAccountNumber);
134 
135                 balance.setBalanceTypeCode(array[i++].toString());
136                 balance.setObjectCode(array[i++].toString());
137 
138                 String subObjectCode = isConsolidated ? Constant.CONSOLIDATED_SUB_OBJECT_CODE : array[i++].toString();
139                 balance.setSubObjectCode(subObjectCode);
140 
141                 String objectTypeCode = isConsolidated ? Constant.CONSOLIDATED_OBJECT_TYPE_CODE : array[i++].toString();
142                 balance.setObjectTypeCode(objectTypeCode);
143 
144                 KualiDecimal annualAmount = new KualiDecimal(array[i++].toString());
145                 balance.setAccountLineAnnualBalanceAmount(annualAmount);
146 
147                 KualiDecimal beginningAmount = new KualiDecimal(array[i++].toString());
148                 balance.setBeginningBalanceLineAmount(beginningAmount);
149 
150                 KualiDecimal CGBeginningAmount = new KualiDecimal(array[i].toString());
151                 balance.setContractsGrantsBeginningBalanceAmount(CGBeginningAmount);
152 
153                 KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance);
154                 balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount);
155 
156                 balanceCollection.add(balance);
157             }
158         }
159         return balanceCollection;
160     }
161 
162     /**
163      * Allows an updating of pending entry records before they are applied to the inquiry results
164      * 
165      * @param entryCollection a collection of balance entries
166      * @param fieldValues the map containing the search fields and values
167      * @param isApproved flag whether the approved entries or all entries will be processed
168      * @param isConsolidated flag whether the results are consolidated or not
169      * @param isCostShareExcluded flag whether the user selects to see the results with cost share subaccount
170      * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableImpl#updateEntryCollection(java.util.Collection, java.util.Map,
171      *      boolean, boolean, boolean)
172      */
173     @Override
174     protected void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) {
175 
176         // convert the field names of balance object into corresponding ones of pending entry object
177         Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues);
178 
179         UniversityDate today = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate();
180         String currentFiscalPeriodCode = today.getUniversityFiscalAccountingPeriod();
181         Integer currentFiscalYear = today.getUniversityFiscalYear();
182 
183         // use the pending entry to update the input entry collection
184         Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForCashBalance(pendingEntryFieldValues, isApproved);
185         while (pendingEntryIterator.hasNext()) {
186             GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next();
187 
188             // Fix the fiscal period/year if they are null
189             // Don't want to use the GLPE service.fillInFiscalPeriodYear. It totally kills performance.
190             // generalLedgerPendingEntryService.fillInFiscalPeriodYear(pendingEntry);
191 
192             if (pendingEntry.getUniversityFiscalYear() == null) {
193                 pendingEntry.setUniversityFiscalYear(currentFiscalYear);
194             }
195 
196             if (pendingEntry.getUniversityFiscalPeriodCode() == null) {
197                 pendingEntry.setUniversityFiscalPeriodCode(currentFiscalPeriodCode);
198             }
199 
200             // if consolidated, change the following fields into the default values for consolidation
201             if (isConsolidated) {
202                 pendingEntry.setSubAccountNumber(Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER);
203                 pendingEntry.setFinancialSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE);
204                 pendingEntry.setFinancialObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE);
205             }
206             Balance balance = postBalance.findBalance(entryCollection, pendingEntry);
207             postBalance.updateBalance(pendingEntry, balance);
208 
209             KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance);
210             balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount);
211         }
212     }
213 
214     // calculate the total available cash amont of the given balance record
215     private KualiDecimal getTotalAvailableCashAmount(Balance balance) {
216         KualiDecimal annualAmount = balance.getAccountLineAnnualBalanceAmount();
217         KualiDecimal beginningAmount = balance.getBeginningBalanceLineAmount();
218         KualiDecimal CGBeginningAmount = balance.getContractsGrantsBeginningBalanceAmount();
219 
220         KualiDecimal totalAvailableAmount = annualAmount.add(beginningAmount);
221         totalAvailableAmount = totalAvailableAmount.add(CGBeginningAmount);
222 
223         return totalAvailableAmount;
224     }
225 
226     /**
227      * Sets the postBalance attribute value.
228      * 
229      * @param postBalance The postBalance to set.
230      */
231     public void setPostBalance(BalanceCalculator postBalance) {
232         this.postBalance = postBalance;
233     }
234 
235     /**
236      * Sets the balanceService attribute value.
237      * 
238      * @param balanceService The balanceService to set.
239      */
240     public void setBalanceService(BalanceService balanceService) {
241         this.balanceService = balanceService;
242     }
243 
244     @Override
245     public List<Row> getRows() {
246         // TODO Auto-generated method stub
247         List<Row> rows = super.getRows();
248 
249         // look for field and replace BO class
250         for (Iterator iter = rows.iterator(); iter.hasNext();) {
251             Row row = (Row) iter.next();
252             for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
253                 Field field = (Field) iterator.next();
254 
255                 if (ObjectUtils.isNotNull(field) && StringUtils.equalsIgnoreCase(field.getPropertyName(), OLEPropertyConstants.ACCOUNT_NUMBER)) {
256                     field.setQuickFinderClassNameImpl(Account.class.getName());
257                 }
258             }
259         }
260 
261         return rows;
262     }
263 
264 }