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