001/* 002 * Copyright 2006 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 */ 016package org.kuali.ole.gl.web.struts; 017 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.List; 024import java.util.Map; 025 026import javax.servlet.ServletException; 027import javax.servlet.http.HttpServletRequest; 028import javax.servlet.http.HttpServletResponse; 029 030import org.apache.commons.lang.StringUtils; 031import org.apache.struts.action.ActionForm; 032import org.apache.struts.action.ActionForward; 033import org.apache.struts.action.ActionMapping; 034import org.kuali.ole.coa.businessobject.Account; 035import org.kuali.ole.coa.businessobject.Chart; 036import org.kuali.ole.coa.businessobject.ObjectCode; 037import org.kuali.ole.gl.Constant; 038import org.kuali.ole.gl.ObjectHelper; 039import org.kuali.ole.gl.businessobject.AccountBalance; 040import org.kuali.ole.gl.businessobject.lookup.AccountBalanceByConsolidationLookupableHelperServiceImpl; 041import org.kuali.ole.sys.OLEConstants; 042import org.kuali.ole.sys.OLEKeyConstants; 043import org.kuali.ole.sys.OLEPropertyConstants; 044import org.kuali.ole.sys.context.SpringContext; 045import org.kuali.rice.core.api.config.property.ConfigurationService; 046import org.kuali.rice.kns.lookup.Lookupable; 047import org.kuali.rice.kns.service.DataDictionaryService; 048import org.kuali.rice.kns.web.struts.action.KualiAction; 049import org.kuali.rice.kns.web.struts.form.LookupForm; 050import org.kuali.rice.kns.web.ui.Field; 051import org.kuali.rice.kns.web.ui.ResultRow; 052import org.kuali.rice.kns.web.ui.Row; 053import org.kuali.rice.krad.lookup.CollectionIncomplete; 054import org.kuali.rice.krad.service.BusinessObjectService; 055import org.kuali.rice.krad.util.GlobalVariables; 056import org.kuali.rice.krad.util.KRADConstants; 057 058/** 059 * This class handles Actions for lookup flow 060 */ 061 062public class BalanceInquiryAction extends KualiAction { 063 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalanceInquiryAction.class); 064 065 private static final String TOTALS_TABLE_KEY = "totalsTable"; 066 067 private ConfigurationService kualiConfigurationService; 068 protected DataDictionaryService dataDictionaryService; 069 private String[] totalTitles; 070 071 public BalanceInquiryAction() { 072 super(); 073 kualiConfigurationService = SpringContext.getBean(ConfigurationService.class); 074 dataDictionaryService = SpringContext.getBean(DataDictionaryService.class); 075 } 076 077 /** 078 * Sets up total titles 079 */ 080 private void setTotalTitles() { 081 totalTitles = new String[7]; 082 083 totalTitles[0] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME); 084 totalTitles[1] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME_FROM_TRANSFERS); 085 totalTitles[2] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.INCOME_TOTAL); 086 totalTitles[3] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE); 087 totalTitles[4] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE_FROM_TRANSFERS); 088 totalTitles[5] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.EXPENSE_TOTAL); 089 totalTitles[6] = kualiConfigurationService.getPropertyValueAsString(OLEKeyConstants.AccountBalanceService.TOTAL); 090 091 } 092 093 /** 094 * Returns an array of total titles 095 * 096 * @return array of total titles 097 */ 098 private String[] getTotalTitles() { 099 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}