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.web.struts;
17  
18  import java.io.IOException;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.servlet.ServletException;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.apache.commons.lang.StringUtils;
31  import org.apache.struts.action.ActionForm;
32  import org.apache.struts.action.ActionForward;
33  import org.apache.struts.action.ActionMapping;
34  import org.kuali.ole.coa.businessobject.Account;
35  import org.kuali.ole.coa.businessobject.Chart;
36  import org.kuali.ole.coa.businessobject.ObjectCode;
37  import org.kuali.ole.gl.Constant;
38  import org.kuali.ole.gl.ObjectHelper;
39  import org.kuali.ole.gl.businessobject.AccountBalance;
40  import org.kuali.ole.gl.businessobject.lookup.AccountBalanceByConsolidationLookupableHelperServiceImpl;
41  import org.kuali.ole.sys.OLEConstants;
42  import org.kuali.ole.sys.OLEKeyConstants;
43  import org.kuali.ole.sys.OLEPropertyConstants;
44  import org.kuali.ole.sys.context.SpringContext;
45  import org.kuali.rice.core.api.config.property.ConfigurationService;
46  import org.kuali.rice.kns.lookup.Lookupable;
47  import org.kuali.rice.kns.service.DataDictionaryService;
48  import org.kuali.rice.kns.web.struts.action.KualiAction;
49  import org.kuali.rice.kns.web.struts.form.LookupForm;
50  import org.kuali.rice.kns.web.ui.Field;
51  import org.kuali.rice.kns.web.ui.ResultRow;
52  import org.kuali.rice.kns.web.ui.Row;
53  import org.kuali.rice.krad.lookup.CollectionIncomplete;
54  import org.kuali.rice.krad.service.BusinessObjectService;
55  import org.kuali.rice.krad.util.GlobalVariables;
56  import org.kuali.rice.krad.util.KRADConstants;
57  
58  /**
59   * This class handles Actions for lookup flow
60   */
61  
62  public class BalanceInquiryAction extends KualiAction {
63      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalanceInquiryAction.class);
64  
65      private static final String TOTALS_TABLE_KEY = "totalsTable";
66  
67      private ConfigurationService kualiConfigurationService;
68      protected DataDictionaryService dataDictionaryService;
69      private String[] totalTitles;
70  
71      public BalanceInquiryAction() {
72          super();
73          kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
74          dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
75      }
76  
77      /**
78       * Sets up total titles
79       */
80      private void setTotalTitles() {
81          totalTitles = new String[7];
82  
83          totalTitles[0] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME);
84          totalTitles[1] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME_FROM_TRANSFERS);
85          totalTitles[2] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME_TOTAL);
86          totalTitles[3] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE);
87          totalTitles[4] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE_FROM_TRANSFERS);
88          totalTitles[5] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE_TOTAL);
89          totalTitles[6] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.TOTAL);
90  
91      }
92  
93      /**
94       * Returns an array of total titles
95       * 
96       * @return array of total titles
97       */
98      private String[] getTotalTitles() {
99          if (null == totalTitles) {
100             setTotalTitles();
101         }
102 
103         return totalTitles;
104     }
105 
106     public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
107         return mapping.findForward(OLEConstants.MAPPING_BASIC);
108     }
109 
110     /**
111      * Search - sets the values of the data entered on the form on the jsp into a map and then searches for the results.
112      * 
113      * @param mapping
114      * @param form
115      * @param request
116      * @param response
117      * @return
118      * @throws Exception
119      * 
120      * KRAD Conversion: Lookupable performs customization of the results if 
121      * account balance by consolidation. The result rows are added to a collection 
122      * based on field's actual size if truncated is > 7.
123      * 
124      * Fields are in data dictionary for bo Balance.
125      */
126     public boolean validateChartCode(String chartCode) {
127         Map searchMap = new HashMap();
128         searchMap.put(OLEConstants.CHART_CODE, chartCode);
129         Chart chart = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Chart.class, searchMap);
130         if (chart != null) {
131             return true;
132         }
133         return false;
134     }
135 
136     public boolean validateAccountNumber(String accountNumber) {
137         Map searchMap = new HashMap();
138         searchMap.put(OLEConstants.ACCOUNT_NUMBER, accountNumber);
139         Account account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Account.class, searchMap);
140         if (account != null) {
141             return true;
142         }
143         return false;
144     }
145 
146     public boolean validateObjectCode(String objectCode) {
147         Map searchMap = new HashMap();
148         searchMap.put(OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, objectCode);
149         ObjectCode code = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(ObjectCode.class, searchMap);
150         if (code != null) {
151             return true;
152         }
153         return false;
154     }
155 
156     public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
157         BalanceInquiryForm lookupForm = (BalanceInquiryForm) form;
158 
159         // check consolidation option and sub-account number
160         Map fieldValues = lookupForm.getFields();
161         String accountNumber = null;
162         String chartCode = null;
163         String objectCode = null;
164         if (fieldValues.get(OLEConstants.ACCOUNT_NUMBER) != null) {
165             accountNumber = fieldValues.get(OLEConstants.ACCOUNT_NUMBER).toString();
166         }
167         if (fieldValues.get(OLEConstants.CHART_CODE) != null) {
168             chartCode = fieldValues.get(OLEConstants.CHART_CODE).toString();
169         }
170         if (fieldValues.get(OLEConstants.OBJECT_CODE) != null) {
171             objectCode = fieldValues.get(OLEConstants.OBJECT_CODE).toString();
172         }
173         if (chartCode != null && !StringUtils.isEmpty(chartCode) && !validateChartCode(chartCode)) {
174             GlobalVariables.getMessageMap().putError(OLEConstants.DOCUMENT_ERRORS, OLEKeyConstants.ERROR_CUSTOM, new String[]{OLEConstants.CHART_CODE_NOT_FOUND});
175         }
176         if (accountNumber != null && !StringUtils.isEmpty(accountNumber) && !validateAccountNumber(accountNumber)) {
177             GlobalVariables.getMessageMap().putError(OLEConstants.DOCUMENT_ERRORS, OLEKeyConstants.ERROR_CUSTOM, new String[]{OLEConstants.ACC_NO_NOT_FOUND});
178         }
179         if (objectCode != null && !StringUtils.isEmpty(objectCode) && !validateObjectCode(objectCode)) {
180             GlobalVariables.getMessageMap().putError(OLEConstants.DOCUMENT_ERRORS, OLEKeyConstants.ERROR_CUSTOM, new String[]{OLEConstants.OBJ_CODE_NOT_FOUND});
181         }
182         String consolidationOption = (String) fieldValues.get(Constant.CONSOLIDATION_OPTION);
183         String subAccountNumber = (String) fieldValues.get(Constant.SUB_ACCOUNT_OPTION);
184         if (Constant.EXCLUDE_SUBACCOUNTS.equals(consolidationOption) && !subAccountNumber.equals("")){
185             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, OLEKeyConstants.ERROR_BALANCE_CONSOLIDATION_EXCLUDE_SUBACCOUNT);
186         }
187         
188         Lookupable lookupable = lookupForm.getLookupable();
189 
190         if (lookupable == null) {
191             LOG.error("Lookupable is null.");
192             throw new RuntimeException("Lookupable is null.");
193         }
194 
195         Collection displayList = new ArrayList();
196         List<ResultRow> resultTable = new ArrayList<ResultRow>();
197 
198         lookupable.validateSearchParameters(lookupForm.getFields());
199 
200         try {
201             displayList = lookupable.performLookup(lookupForm, resultTable, true);
202 
203             Object[] resultTableAsArray = resultTable.toArray();
204 
205             CollectionIncomplete incompleteDisplayList = (CollectionIncomplete) displayList;
206             Long totalSize = ((CollectionIncomplete) displayList).getActualSizeIfTruncated();
207 
208             request.setAttribute(OLEConstants.REQUEST_SEARCH_RESULTS_SIZE, totalSize);
209 
210             // TODO: use inheritance instead of this if statement
211             if (lookupable.getLookupableHelperService() instanceof AccountBalanceByConsolidationLookupableHelperServiceImpl) {
212 
213                 Collection totalsTable = new ArrayList();
214 
215                 int listIndex = 0;
216                 int arrayIndex = 0;
217                 int listSize = incompleteDisplayList.size();
218 
219                 for (; listIndex < listSize;) {
220 
221                     AccountBalance balance = (AccountBalance) incompleteDisplayList.get(listIndex);
222 
223                     boolean ok = ObjectHelper.isOneOf(balance.getTitle(), getTotalTitles());
224                     if (ok) {
225 
226                         if (totalSize > 7) {
227                             totalsTable.add(resultTableAsArray[arrayIndex]);
228                         }
229                         resultTable.remove(resultTableAsArray[arrayIndex]);
230 
231                         incompleteDisplayList.remove(balance);
232                         // account for the removal of the balance which resizes the list
233                         listIndex--;
234                         listSize--;
235 
236                     }
237 
238                     listIndex++;
239                     arrayIndex++;
240 
241                 }
242 
243                 request.setAttribute(OLEConstants.REQUEST_SEARCH_RESULTS, resultTable);
244 
245                 request.setAttribute(TOTALS_TABLE_KEY, totalsTable);
246                 GlobalVariables.getUserSession().addObject(TOTALS_TABLE_KEY, totalsTable);
247 
248             }
249             else {
250 
251                 request.setAttribute(OLEConstants.REQUEST_SEARCH_RESULTS, resultTable);
252 
253             }
254 
255             if (request.getParameter(OLEConstants.SEARCH_LIST_REQUEST_KEY) != null) {
256                 GlobalVariables.getUserSession().removeObject(request.getParameter(OLEConstants.SEARCH_LIST_REQUEST_KEY));
257             }
258 
259             request.setAttribute(OLEConstants.SEARCH_LIST_REQUEST_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(resultTable));
260 
261         }
262         catch (NumberFormatException e) {
263             GlobalVariables.getMessageMap().putError(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, OLEKeyConstants.ERROR_CUSTOM, new String[] { "Fiscal Year must be a four-digit number" });
264         }
265         catch (Exception e) {
266             GlobalVariables.getMessageMap().putError(OLEConstants.DOCUMENT_ERRORS, OLEKeyConstants.ERROR_CUSTOM, new String[] { "Please report the server error." });
267             LOG.error("Application Errors", e);
268         }
269         return mapping.findForward(OLEConstants.MAPPING_BASIC);
270     }
271 
272     /**
273      * Refresh - is called when one quickFinder returns to the previous one. Sets all the values and performs the new search.
274      * 
275      * @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
276      *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
277      *      
278      * KRAD Conversion: Lookupable performs customization of the fields and check for additional fields.
279      *  
280      * Fields are in data dictionary for bo Balance.
281      */
282     @Override
283     public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
284         LookupForm lookupForm = (LookupForm) form;
285         Lookupable lookupable = lookupForm.getLookupable();
286         if (lookupable == null) {
287             LOG.error("Lookupable is null.");
288             throw new RuntimeException("Lookupable is null.");
289         }
290 
291         Map fieldValues = new HashMap();
292         Map values = lookupForm.getFields();
293 
294         for (Iterator iter = lookupable.getRows().iterator(); iter.hasNext();) {
295             Row row = (Row) iter.next();
296 
297             for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
298                 Field field = (Field) iterator.next();
299 
300                 if (field.getPropertyName() != null && !field.getPropertyName().equals("")) {
301                     if (request.getParameter(field.getPropertyName()) != null) {
302                         field.setPropertyValue(request.getParameter(field.getPropertyName()));
303                     }
304                     else if (values.get(field.getPropertyName()) != null) {
305                         field.setPropertyValue(values.get(field.getPropertyName()));
306                     }
307                 }
308                 fieldValues.put(field.getPropertyName(), field.getPropertyValue());
309             }
310         }
311         fieldValues.put(OLEConstants.DOC_FORM_KEY, lookupForm.getFormKey());
312         fieldValues.put(OLEConstants.BACK_LOCATION, lookupForm.getBackLocation());
313 
314         if (lookupable.checkForAdditionalFields(fieldValues)) {
315             for (Iterator iter = lookupable.getRows().iterator(); iter.hasNext();) {
316                 Row row = (Row) iter.next();
317                 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
318                     Field field = (Field) iterator.next();
319                     if (field.getPropertyName() != null && !field.getPropertyName().equals("")) {
320                         if (request.getParameter(field.getPropertyName()) != null) {
321                             field.setPropertyValue(request.getParameter(field.getPropertyName()));
322                             fieldValues.put(field.getPropertyName(), request.getParameter(field.getPropertyName()));
323                         }
324                         else if (values.get(field.getPropertyName()) != null) {
325                             field.setPropertyValue(values.get(field.getPropertyName()));
326                         }
327                     }
328                 }
329             }
330         }
331 
332         return mapping.findForward(OLEConstants.MAPPING_BASIC);
333     }
334 
335     /**
336      * Returns as if return with no value was selected.
337      * 
338      * @param mapping
339      * @param form
340      * @param request
341      * @param response
342      * @return
343      * @throws Exception
344      */
345     public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
346         LookupForm lookupForm = (LookupForm) form;
347 
348         String backUrl = lookupForm.getBackLocation() + "?methodToCall=refresh&docFormKey=" + lookupForm.getFormKey();
349         return new ActionForward(backUrl, true);
350     }
351 
352 
353     /**
354      * Clears the values of all the fields on the jsp.
355      * 
356      * @param mapping
357      * @param form
358      * @param request
359      * @param response
360      * @return
361      * @throws IOException
362      * @throws ServletException
363      * 
364      * KRAD Conversion: Lookupable performs setting/clearing of the field values. 
365      * 
366      * Fields are in data dictionary for bo Balance.
367      */
368     public ActionForward clearValues(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
369         LookupForm lookupForm = (LookupForm) form;
370         Lookupable lookupable = lookupForm.getLookupable();
371         if (lookupable == null) {
372             LOG.error("Lookupable is null.");
373             throw new RuntimeException("Lookupable is null.");
374         }
375 
376         for (Iterator iter = lookupable.getRows().iterator(); iter.hasNext();) {
377             Row row = (Row) iter.next();
378             for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
379                 Field field = (Field) iterator.next();
380                 if (!field.getFieldType().equals(Field.RADIO)) {
381                     field.setPropertyValue(field.getDefaultValue());
382                 }
383             }
384         }
385 
386         return mapping.findForward(OLEConstants.MAPPING_BASIC);
387     }
388 
389     /**
390      * View results from balance inquiry action
391      * 
392      * @param mapping
393      * @param form
394      * @param request
395      * @param response
396      * @return
397      * @throws Exception
398      */
399     public ActionForward viewResults(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
400         request.setAttribute(OLEConstants.SEARCH_LIST_REQUEST_KEY, request.getParameter(OLEConstants.SEARCH_LIST_REQUEST_KEY));
401         request.setAttribute(OLEConstants.REQUEST_SEARCH_RESULTS, GlobalVariables.getUserSession().retrieveObject(request.getParameter(OLEConstants.SEARCH_LIST_REQUEST_KEY)));
402         request.setAttribute(OLEConstants.REQUEST_SEARCH_RESULTS_SIZE, request.getParameter(OLEConstants.REQUEST_SEARCH_RESULTS_SIZE));
403 
404         // TODO: use inheritance instead of this if statement
405         if (((BalanceInquiryForm) form).getLookupable().getLookupableHelperService() instanceof AccountBalanceByConsolidationLookupableHelperServiceImpl) {
406             Object totalsTable = GlobalVariables.getUserSession().retrieveObject(TOTALS_TABLE_KEY);
407             request.setAttribute(TOTALS_TABLE_KEY, totalsTable);
408         }
409 
410         return mapping.findForward(OLEConstants.MAPPING_BASIC);
411     }
412 
413     public void setConfigurationService(ConfigurationService kcs) {
414         kualiConfigurationService = kcs;
415     }
416 
417     @Override
418     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
419         request.setAttribute(KRADConstants.PARAM_MAINTENANCE_VIEW_MODE, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_LOOKUP);
420         org.kuali.rice.kns.datadictionary.BusinessObjectEntry boe = (org.kuali.rice.kns.datadictionary.BusinessObjectEntry) dataDictionaryService.getDataDictionary().getBusinessObjectEntry(((LookupForm) form).getBusinessObjectClassName());
421         int numCols = boe.getLookupDefinition().getNumOfColumns();
422         if (numCols <= 0) {
423             numCols = KRADConstants.DEFAULT_NUM_OF_COLUMNS; // by default, always show one column.
424         }
425         ((LookupForm) form).setNumColumns(numCols);
426         return super.execute(mapping, form, request, response);
427     }
428 }