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.pdp.web.struts; 017 018 import java.text.MessageFormat; 019 import java.util.List; 020 import java.util.Properties; 021 022 import javax.servlet.http.HttpServletRequest; 023 import javax.servlet.http.HttpServletResponse; 024 025 import org.apache.commons.lang.StringUtils; 026 import org.apache.struts.action.ActionForm; 027 import org.apache.struts.action.ActionForward; 028 import org.apache.struts.action.ActionMapping; 029 import org.kuali.kfs.pdp.PdpKeyConstants; 030 import org.kuali.kfs.pdp.PdpParameterConstants; 031 import org.kuali.kfs.pdp.PdpPropertyConstants; 032 import org.kuali.kfs.pdp.businessobject.Batch; 033 import org.kuali.kfs.pdp.service.BatchMaintenanceService; 034 import org.kuali.kfs.pdp.util.PdpBatchQuestionCallback; 035 import org.kuali.kfs.sys.KFSConstants; 036 import org.kuali.kfs.sys.context.SpringContext; 037 import org.kuali.rice.kim.bo.Person; 038 import org.kuali.rice.kns.question.ConfirmationQuestion; 039 import org.kuali.rice.kns.service.KNSServiceLocator; 040 import org.kuali.rice.kns.service.KualiConfigurationService; 041 import org.kuali.rice.kns.util.ErrorMessage; 042 import org.kuali.rice.kns.util.GlobalVariables; 043 import org.kuali.rice.kns.util.KNSConstants; 044 import org.kuali.rice.kns.util.MessageMap; 045 import org.kuali.rice.kns.util.UrlFactory; 046 import org.kuali.rice.kns.web.struts.action.KualiAction; 047 048 /** 049 * This class defines actions for Batch (cancel, hold, remove hold). 050 */ 051 public class BatchAction extends KualiAction { 052 053 private BatchMaintenanceService batchMaintenanceService; 054 055 /** 056 * Constructs a BatchAction.java. 057 */ 058 public BatchAction() { 059 setBatchMaintenanceService(SpringContext.getBean(BatchMaintenanceService.class)); 060 } 061 062 063 /** 064 * This method confirms and performs batch cancel. 065 * 066 * @param mapping 067 * @param form 068 * @param request 069 * @param response 070 * @return 071 * @throws Exception 072 */ 073 public ActionForward confirmAndCancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 074 075 PdpBatchQuestionCallback callback = new PdpBatchQuestionCallback() { 076 public boolean doPostQuestion(String batchIdString, String cancelNote, Person user) { 077 return performCancel(batchIdString, cancelNote, user); 078 } 079 }; 080 return askQuestionWithInput(mapping, form, request, response, PdpKeyConstants.BatchConstants.Confirmation.CANCEL_BATCH_QUESTION, PdpKeyConstants.BatchConstants.Confirmation.CANCEL_BATCH_MESSAGE, PdpKeyConstants.BatchConstants.Messages.BATCH_SUCCESSFULLY_CANCELED, "confirmAndCancel", callback); 081 082 } 083 084 /** 085 * This method cancels a batch. 086 * 087 * @param batchIdString a string representing the batch id 088 * @param cancelNote the cancelation note entered by the user 089 * @param user the current user 090 */ 091 private boolean performCancel(String batchIdString, String cancelNote, Person user) { 092 try { 093 Integer batchId = Integer.parseInt(batchIdString); 094 return batchMaintenanceService.cancelPendingBatch(batchId, cancelNote, user); 095 } 096 catch (NumberFormatException e) { 097 GlobalVariables.getMessageMap().putError(PdpPropertyConstants.BatchConstants.BATCH_ID, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_BATCH_ID_IS_NOT_NUMERIC); 098 return false; 099 } 100 101 } 102 103 /** 104 * This method confirms and performs batch hold. 105 * 106 * @param mapping 107 * @param form 108 * @param request 109 * @param response 110 * @return 111 * @throws Exception 112 */ 113 public ActionForward confirmAndHold(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 114 115 PdpBatchQuestionCallback callback = new PdpBatchQuestionCallback() { 116 public boolean doPostQuestion(String batchIdString, String note, Person user) { 117 return performHold(batchIdString, note, user); 118 } 119 }; 120 return askQuestionWithInput(mapping, form, request, response, PdpKeyConstants.BatchConstants.Confirmation.HOLD_BATCH_QUESTION, PdpKeyConstants.BatchConstants.Confirmation.HOLD_BATCH_MESSAGE, PdpKeyConstants.BatchConstants.Messages.BATCH_SUCCESSFULLY_HOLD, "confirmAndHold", callback); 121 } 122 123 /** 124 * This method holds a batch 125 * 126 * @param batchIdString 127 * @param holdNote 128 * @param user 129 * @throws PdpException 130 */ 131 private boolean performHold(String batchIdString, String holdNote, Person user) { 132 try { 133 Integer batchId = Integer.parseInt(batchIdString); 134 return batchMaintenanceService.holdPendingBatch(batchId, holdNote, user); 135 } 136 catch (NumberFormatException e) { 137 GlobalVariables.getMessageMap().putError(PdpPropertyConstants.BatchConstants.BATCH_ID, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_BATCH_ID_IS_NOT_NUMERIC); 138 return false; 139 } 140 141 } 142 143 /** 144 * This method confirms and peforms remove hold on batch action. 145 * 146 * @param mapping 147 * @param form 148 * @param request 149 * @param response 150 * @return 151 * @throws Exception 152 */ 153 public ActionForward confirmAndRemoveHold(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 154 PdpBatchQuestionCallback callback = new PdpBatchQuestionCallback() { 155 public boolean doPostQuestion(String batchIdString, String note, Person user) { 156 return performRemoveHold(batchIdString, note, user); 157 } 158 }; 159 return askQuestionWithInput(mapping, form, request, response, PdpKeyConstants.BatchConstants.Confirmation.REMOVE_HOLD_BATCH_QUESTION, PdpKeyConstants.BatchConstants.Confirmation.REMOVE_HOLD_BATCH_MESSAGE, PdpKeyConstants.BatchConstants.Messages.HOLD_SUCCESSFULLY_REMOVED_ON_BATCH, "confirmAndRemoveHold", callback); 160 } 161 162 /** 163 * This method removes a batch hold. 164 * 165 * @param batchIdString 166 * @param changeText 167 * @param user 168 * @throws PdpException 169 */ 170 private boolean performRemoveHold(String batchIdString, String changeText, Person user) { 171 try { 172 Integer batchId = Integer.parseInt(batchIdString); 173 return batchMaintenanceService.removeBatchHold(batchId, changeText, user); 174 } 175 catch (NumberFormatException e) { 176 GlobalVariables.getMessageMap().putError(PdpPropertyConstants.BatchConstants.BATCH_ID, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_BATCH_ID_IS_NOT_NUMERIC); 177 return false; 178 } 179 180 } 181 182 /** 183 * This method prompts for a reason to perfomr an action on a batch (cancel, hold, remove hold). 184 * 185 * @param mapping 186 * @param form 187 * @param request 188 * @param response 189 * @param confirmationQuestion 190 * @param confirmationText 191 * @param caller 192 * @param callback 193 * @return 194 * @throws Exception 195 */ 196 private ActionForward askQuestionWithInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String confirmationQuestion, String confirmationText, String successMessage, String caller, PdpBatchQuestionCallback callback) throws Exception { 197 Object question = request.getParameter(KNSConstants.QUESTION_INST_ATTRIBUTE_NAME); 198 String reason = request.getParameter(KNSConstants.QUESTION_REASON_ATTRIBUTE_NAME); 199 String noteText = KFSConstants.EMPTY_STRING; 200 Person person = GlobalVariables.getUserSession().getPerson(); 201 boolean actionStatus; 202 String message = KFSConstants.EMPTY_STRING; 203 204 String batchId = request.getParameter(PdpParameterConstants.BatchConstants.BATCH_ID_PARAM); 205 if (batchId == null) { 206 batchId = request.getParameter(KNSConstants.QUESTION_CONTEXT); 207 } 208 209 KualiConfigurationService kualiConfiguration = KNSServiceLocator.getKualiConfigurationService(); 210 confirmationText = kualiConfiguration.getPropertyString(confirmationText); 211 confirmationText = MessageFormat.format(confirmationText, batchId); 212 213 if (question == null) { 214 // ask question if not already asked 215 return this.performQuestionWithInput(mapping, form, request, response, confirmationQuestion, confirmationText, KNSConstants.CONFIRMATION_QUESTION, caller, batchId); 216 } 217 else { 218 Object buttonClicked = request.getParameter(KNSConstants.QUESTION_CLICKED_BUTTON); 219 if ((confirmationQuestion.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { 220 actionStatus = false; 221 } 222 else { 223 noteText = reason; 224 int noteTextLength = (reason == null) ? 0 : noteText.length(); 225 int noteTextMaxLength = PdpKeyConstants.BatchConstants.Confirmation.NOTE_TEXT_MAX_LENGTH; 226 227 if (StringUtils.isBlank(reason)) { 228 229 if (reason == null) { 230 // prevent a NPE by setting the reason to a blank string 231 reason = KFSConstants.EMPTY_STRING; 232 } 233 return this.performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, confirmationQuestion, confirmationText, KNSConstants.CONFIRMATION_QUESTION, KFSConstants.MAPPING_BASIC, batchId, reason, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOTE_EMPTY, KNSConstants.QUESTION_REASON_ATTRIBUTE_NAME, ""); 234 } 235 else if (noteTextLength > noteTextMaxLength) { 236 return this.performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, confirmationQuestion, confirmationText, KNSConstants.CONFIRMATION_QUESTION, KFSConstants.MAPPING_BASIC, batchId, reason, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOTE_TOO_LONG, KNSConstants.QUESTION_REASON_ATTRIBUTE_NAME, ""); 237 } 238 239 actionStatus = callback.doPostQuestion(batchId, noteText, person); 240 if (actionStatus) { 241 message = successMessage; 242 } 243 244 } 245 } 246 247 String returnUrl = buildUrl(batchId, actionStatus, message, buildErrorMesageKeyList()); 248 return new ActionForward(returnUrl, true); 249 } 250 251 /** 252 * This method builds the forward url. 253 * 254 * @param batchId the batch id 255 * @param success action status: true if success, false otherwise 256 * @param message the message for the user 257 * @return the build url 258 */ 259 private String buildUrl(String batchId, boolean success, String message, String errorList) { 260 String basePath = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.APPLICATION_URL_KEY); 261 262 Properties parameters = new Properties(); 263 parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KFSConstants.SEARCH_METHOD); 264 parameters.put(KFSConstants.BACK_LOCATION, basePath + "/" + KFSConstants.MAPPING_PORTAL + ".do"); 265 parameters.put(KNSConstants.DOC_FORM_KEY, "88888888"); 266 parameters.put(KFSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, Batch.class.getName()); 267 parameters.put(KFSConstants.HIDE_LOOKUP_RETURN_LINK, "true"); 268 parameters.put(KFSConstants.SUPPRESS_ACTIONS, "false"); 269 parameters.put(PdpPropertyConstants.BatchConstants.BATCH_ID, batchId); 270 parameters.put(PdpParameterConstants.ACTION_SUCCESSFUL_PARAM, String.valueOf(success)); 271 if (message != null && !message.equalsIgnoreCase(KFSConstants.EMPTY_STRING)) { 272 parameters.put(PdpParameterConstants.MESSAGE_PARAM, message); 273 } 274 275 if (StringUtils.isNotEmpty(errorList)) { 276 parameters.put(PdpParameterConstants.ERROR_KEY_LIST_PARAM, errorList); 277 } 278 279 String lookupUrl = UrlFactory.parameterizeUrl(basePath + "/" + KFSConstants.LOOKUP_ACTION, parameters); 280 281 return lookupUrl; 282 } 283 284 /** 285 * This method build a string list of error message keys out of the error map in GlobalVariables 286 * 287 * @return a String representing the list of error message keys 288 */ 289 private String buildErrorMesageKeyList() { 290 MessageMap errorMap = GlobalVariables.getMessageMap(); 291 StringBuffer errorList = new StringBuffer(); 292 293 for (String errorKey : (List<String>) errorMap.getPropertiesWithErrors()) { 294 for (ErrorMessage errorMessage : (List<ErrorMessage>) errorMap.getMessages(errorKey)) { 295 296 errorList.append(errorMessage.getErrorKey()); 297 errorList.append(PdpParameterConstants.ERROR_KEY_LIST_SEPARATOR); 298 } 299 } 300 if (errorList.length() > 0) { 301 errorList.replace(errorList.lastIndexOf(PdpParameterConstants.ERROR_KEY_LIST_SEPARATOR), errorList.lastIndexOf(PdpParameterConstants.ERROR_KEY_LIST_SEPARATOR) + PdpParameterConstants.ERROR_KEY_LIST_SEPARATOR.length(), ""); 302 } 303 304 return errorList.toString(); 305 } 306 307 /** 308 * This method gets the batch maintenance service. 309 * 310 * @return the BatchMaintenanceService 311 */ 312 public BatchMaintenanceService getBatchMaintenanceService() { 313 return batchMaintenanceService; 314 } 315 316 /** 317 * This method sets the batch maintenance service. 318 * 319 * @param batchMaintenanceService 320 */ 321 public void setBatchMaintenanceService(BatchMaintenanceService batchMaintenanceService) { 322 this.batchMaintenanceService = batchMaintenanceService; 323 } 324 325 } 326