View Javadoc
1   package org.kuali.ole.gl.businessobject.lookup;
2   
3   import org.apache.commons.lang.StringUtils;
4   
5   import org.kuali.ole.gl.Constant;
6   import org.kuali.ole.gl.GeneralLedgerConstants;
7   import org.kuali.ole.gl.OJBUtility;
8   import org.kuali.ole.gl.batch.service.BalanceCalculator;
9   import org.kuali.ole.gl.batch.service.impl.PostBalance;
10  import org.kuali.ole.gl.businessobject.Balance;
11  import org.kuali.ole.gl.businessobject.CashBalance;
12  import org.kuali.ole.gl.service.BalanceService;
13  import org.kuali.ole.sys.OLEConstants;
14  import org.kuali.ole.sys.OLEPropertyConstants;
15  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
16  import org.kuali.ole.sys.businessobject.UniversityDate;
17  import org.kuali.ole.sys.context.SpringContext;
18  import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
19  import org.kuali.ole.sys.service.UniversityDateService;
20  import org.kuali.rice.core.api.util.RiceKeyConstants;
21  import org.kuali.rice.core.api.util.type.KualiDecimal;
22  import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
23  
24  import org.kuali.rice.krad.lookup.LookupForm;
25  import org.kuali.rice.krad.lookup.LookupableImpl;
26  
27  import org.kuali.rice.krad.util.GlobalVariables;
28  import org.kuali.rice.krad.util.KRADConstants;
29  
30  import java.util.*;
31  
32  /**
33   * Created by arunag on 9/29/14.
34   */
35  public class OLECashBalanceLookupableImpl extends LookupableImpl {
36  
37      private BalanceCalculator postBalance;
38      //private BalanceService balanceService = SpringContext.getBean(glBalanceService);
39      protected Class businessObjectClass;
40      protected BusinessObjectDictionaryService businessObjectDictionaryService;
41      protected GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
42      protected BalanceService balanceService;
43  
44  
45      public BalanceService getBalanceService() {
46          if(balanceService == null) {
47               balanceService =  SpringContext.getBean(BalanceService.class);
48          }
49          return balanceService;
50      }
51  
52      public void setBalanceService(BalanceService balanceService) {
53          this.balanceService = balanceService;
54      }
55  
56      @Override
57      public Collection<?> performSearch(LookupForm form, Map<String, String> searchCriteria, boolean bounded) {
58  
59  
60          for (Map.Entry<String, String> entry : searchCriteria.entrySet()) {
61              if (entry.getKey().equalsIgnoreCase(OLEConstants.FISCAL_YEAR) && (entry.getValue()==null || entry.getValue().isEmpty())) {
62                  GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,"Fiscal Year is a required field");
63                  return new ArrayList<Object>();
64              }if (entry.getKey().equalsIgnoreCase(OLEConstants.ACCOUNT_NUMBER) && (entry.getValue()==null || entry.getValue().isEmpty())) {
65                  GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,"Account Number is a required field");
66                  return new ArrayList<Object>();
67              }if (entry.getKey().equalsIgnoreCase(OLEConstants.CHART_CODE) && (entry.getValue()==null || entry.getValue().isEmpty())) {
68                  GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,"Chart Code is a required field");
69                  return new ArrayList<Object>();
70              }
71          }
72          String pendingEntryOption = searchCriteria.get(Constant.PENDING_ENTRY_OPTION);
73          String consolidationOption = (String) searchCriteria.get(GeneralLedgerConstants.DummyBusinessObject.CONSOLIDATION_OPTION);
74          boolean isConsolidated = isConsolidationSelected(searchCriteria);
75          if (consolidationOption.equals(Constant.EXCLUDE_SUBACCOUNTS)){
76              searchCriteria.put(Constant.SUB_ACCOUNT_OPTION, OLEConstants.getDashSubAccountNumber());
77              isConsolidated = false;
78          }
79  
80          searchCriteria.remove("dummyBusinessObject.pendingEntryOption");
81  
82          Iterator cashBalanceIterator = getBalanceService().lookupCashBalance(searchCriteria, isConsolidated);
83          Collection searchResultsCollection = this.buildCashBalanceCollection(cashBalanceIterator, isConsolidated);
84  
85  /*
86          if(searchResultsCollection.size() == 0){
87              GlobalVariables.getMessageMap().putInfoForSectionId("resultsPropertyName",
88                      RiceKeyConstants.INFO_LOOKUP_RESULTS_NONE_FOUND);
89          }
90  */
91  
92          // update search results according to the selected pending entry option
93          updateByPendingLedgerEntry(searchResultsCollection, searchCriteria, pendingEntryOption, isConsolidated, false);
94  
95          // get the actual size of all qualified search results
96          Integer recordCount = getBalanceService().getCashBalanceRecordCount(searchCriteria, isConsolidated);
97          Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, searchCriteria, new Balance());
98  
99          //return this.buildSearchResultList(searchResultsCollection, actualSize);
100         return searchResultsCollection;
101     }
102 
103     /**
104      * This method builds the cash balance collection based on the input iterator
105      *
106      * @param iterator the iterator of search results of avaiable cash balance
107      * @return the cash balance collection
108      */
109     private Collection buildCashBalanceCollection(Iterator iterator, boolean isConsolidated) {
110         Collection balanceCollection = new ArrayList();
111 
112         while (iterator.hasNext()) {
113             Object cashBalance = iterator.next();
114 
115             if (cashBalance.getClass().isArray()) {
116                 int i = 0;
117                 Object[] array = (Object[]) cashBalance;
118                 Balance balance = new CashBalance();
119 
120                 balance.setUniversityFiscalYear(new Integer(array[i++].toString()));
121                 balance.setChartOfAccountsCode(array[i++].toString());
122                 balance.setAccountNumber(array[i++].toString());
123 
124                 String subAccountNumber = isConsolidated ? Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER : array[i++].toString();
125                 balance.setSubAccountNumber(subAccountNumber);
126 
127                 balance.setBalanceTypeCode(array[i++].toString());
128                 balance.setObjectCode(array[i++].toString());
129 
130                 String subObjectCode = isConsolidated ? Constant.CONSOLIDATED_SUB_OBJECT_CODE : array[i++].toString();
131                 balance.setSubObjectCode(subObjectCode);
132 
133                 String objectTypeCode = isConsolidated ? Constant.CONSOLIDATED_OBJECT_TYPE_CODE : array[i++].toString();
134                 balance.setObjectTypeCode(objectTypeCode);
135 
136                 KualiDecimal annualAmount = new KualiDecimal(array[i++].toString());
137                 balance.setAccountLineAnnualBalanceAmount(annualAmount);
138 
139                 KualiDecimal beginningAmount = new KualiDecimal(array[i++].toString());
140                 balance.setBeginningBalanceLineAmount(beginningAmount);
141 
142                 KualiDecimal CGBeginningAmount = new KualiDecimal(array[i].toString());
143                 balance.setContractsGrantsBeginningBalanceAmount(CGBeginningAmount);
144 
145                 KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance);
146                 balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount);
147 
148                 balanceCollection.add(balance);
149             }
150         }
151         return balanceCollection;
152     }
153 
154 
155 
156     protected void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) {
157 
158         // convert the field names of balance object into corresponding ones of pending entry object
159         Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues);
160 
161         UniversityDate today = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate();
162         String currentFiscalPeriodCode = today.getUniversityFiscalAccountingPeriod();
163         Integer currentFiscalYear = today.getUniversityFiscalYear();
164 
165         // use the pending entry to update the input entry collection
166         Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForCashBalance(pendingEntryFieldValues, isApproved);
167         while (pendingEntryIterator.hasNext()) {
168             GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next();
169 
170             // Fix the fiscal period/year if they are null
171             // Don't want to use the GLPE service.fillInFiscalPeriodYear. It totally kills performance.
172             // generalLedgerPendingEntryService.fillInFiscalPeriodYear(pendingEntry);
173 
174             if (pendingEntry.getUniversityFiscalYear() == null) {
175                 pendingEntry.setUniversityFiscalYear(currentFiscalYear);
176             }
177 
178             if (pendingEntry.getUniversityFiscalPeriodCode() == null) {
179                 pendingEntry.setUniversityFiscalPeriodCode(currentFiscalPeriodCode);
180             }
181 
182             // if consolidated, change the following fields into the default values for consolidation
183             if (isConsolidated) {
184                 pendingEntry.setSubAccountNumber(Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER);
185                 pendingEntry.setFinancialSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE);
186                 pendingEntry.setFinancialObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE);
187             }
188             Balance balance = getPostBalance().findBalance(entryCollection, pendingEntry);
189             getPostBalance().updateBalance(pendingEntry, balance);
190 
191             KualiDecimal totalAvailableAmount = this.getTotalAvailableCashAmount(balance);
192             balance.getDummyBusinessObject().setGenericAmount(totalAvailableAmount);
193         }
194     }
195 
196     // calculate the total available cash amont of the given balance record
197     private KualiDecimal getTotalAvailableCashAmount(Balance balance) {
198         KualiDecimal annualAmount = balance.getAccountLineAnnualBalanceAmount();
199         KualiDecimal beginningAmount = balance.getBeginningBalanceLineAmount();
200         KualiDecimal CGBeginningAmount = balance.getContractsGrantsBeginningBalanceAmount();
201 
202         KualiDecimal totalAvailableAmount = annualAmount.add(beginningAmount);
203         totalAvailableAmount = totalAvailableAmount.add(CGBeginningAmount);
204 
205         return totalAvailableAmount;
206     }
207 
208 
209 
210     protected String getSelectedPendingEntryOption(Map fieldValues) {
211         // truncate the non-property filed
212         String pendingEntryOption = (String) fieldValues.get(Constant.PENDING_ENTRY_OPTION);
213         fieldValues.remove(Constant.PENDING_ENTRY_OPTION);
214 
215         return pendingEntryOption;
216     }
217 
218     protected boolean isConsolidationSelected(Map fieldValues) {
219         // truncate the non-property filed
220         String consolidationOption = (String) fieldValues.get(Constant.CONSOLIDATION_OPTION);
221         fieldValues.remove(Constant.CONSOLIDATION_OPTION);
222 
223         // detail option would be used
224         if (Constant.DETAIL.equals(consolidationOption)) {
225             return false;
226         }
227 
228         // if the subAccountNumber is specified, detail option could be used
229         String subAccountNumber = (String) fieldValues.get(OLEPropertyConstants.SUB_ACCOUNT_NUMBER);
230         if (!StringUtils.isBlank(subAccountNumber)) {
231             //this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
232             return false;
233         }
234 
235         // if the subObjectCode is specified, detail option could be used
236         String subObjectCode = (String) fieldValues.get(OLEPropertyConstants.SUB_OBJECT_CODE);
237         if (!StringUtils.isBlank(subObjectCode)) {
238             //this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
239             return false;
240         }
241 
242         // if the objectTypeCode is specified, detail option could be used
243         String objectTypeCode = (String) fieldValues.get(OLEPropertyConstants.OBJECT_TYPE_CODE);
244         if (!StringUtils.isBlank(objectTypeCode)) {
245             //this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
246             return false;
247         }
248         return true;
249     }
250 
251     protected void updateByPendingLedgerEntry(Collection entryCollection, Map fieldValues, String pendingEntryOption, boolean isConsolidated, boolean isCostShareInclusive) {
252 
253         // determine if search results need to be updated by pending ledger entries
254         if (Constant.ALL_PENDING_ENTRY.equals(pendingEntryOption)) {
255             updateEntryCollection(entryCollection, fieldValues, false, isConsolidated, isCostShareInclusive);
256         }
257         else if (Constant.APPROVED_PENDING_ENTRY.equals(pendingEntryOption)) {
258             updateEntryCollection(entryCollection, fieldValues, true, isConsolidated, isCostShareInclusive);
259         }
260     }
261 /*
262     protected List buildSearchResultList(Collection searchResultsCollection, Long actualSize) {
263         CollectionIncomplete results = new CollectionIncomplete(searchResultsCollection, actualSize);
264 
265         // sort list if default sort column given
266         List searchResults = results;
267         List defaultSortColumns = getDefaultSortColumns();
268         if (defaultSortColumns.size() > 0) {
269             Collections.sort(results, new BeanPropertyComparator(defaultSortColumns, true));
270         }
271         return searchResults;
272     }*/
273 
274     public Class getBusinessObjectClass() {
275         return businessObjectClass;
276     }
277 
278     protected GeneralLedgerPendingEntryService getGeneralLedgerPendingEntryService() {
279         if(generalLedgerPendingEntryService == null){
280             generalLedgerPendingEntryService = SpringContext.getBean(GeneralLedgerPendingEntryService.class);
281         }
282         return generalLedgerPendingEntryService;
283     }
284 
285     public BalanceCalculator getPostBalance() {
286         if(postBalance == null){
287             postBalance = SpringContext.getBean(BalanceCalculator.class);
288         }
289         return postBalance;
290     }
291 
292     public void setPostBalance(BalanceCalculator postBalance) {
293         this.postBalance = postBalance;
294     }
295 }