View Javadoc
1   /*
2    * Copyright 2008 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.module.purap.document.web.struts;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.struts.action.ActionForm;
20  import org.apache.struts.action.ActionForward;
21  import org.apache.struts.action.ActionMapping;
22  import org.kuali.ole.module.purap.PurapKeyConstants;
23  import org.kuali.ole.module.purap.document.ReceivingDocument;
24  import org.kuali.ole.module.purap.util.ReceivingQuestionCallback;
25  import org.kuali.ole.sys.OLEConstants;
26  import org.kuali.ole.sys.context.SpringContext;
27  import org.kuali.ole.sys.document.web.struts.FinancialSystemTransactionalDocumentActionBase;
28  import org.kuali.rice.core.api.config.property.ConfigurationService;
29  import org.kuali.rice.kns.question.ConfirmationQuestion;
30  import org.kuali.rice.kns.service.DataDictionaryService;
31  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
32  import org.kuali.rice.krad.bo.Note;
33  import org.kuali.rice.krad.util.ObjectUtils;
34  
35  import javax.servlet.http.HttpServletRequest;
36  import javax.servlet.http.HttpServletResponse;
37  import java.util.Iterator;
38  import java.util.TreeMap;
39  
40  public class ReceivingBaseAction extends FinancialSystemTransactionalDocumentActionBase {
41  
42      /**
43       * A wrapper method which prompts for a reason to hold a payment request or credit memo.
44       *
45       * @param mapping      An ActionMapping
46       * @param form         An ActionForm
47       * @param request      The HttpServletRequest
48       * @param response     The HttpServletResponse
49       * @param questionType A String used to distinguish which question is being asked
50       * @param notePrefix   A String explaining what action was taken, to be prepended to the note containing the reason, which gets
51       *                     written to the document
52       * @param operation    A one-word String description of the action to be taken, to be substituted into the message. (Can be an
53       *                     empty String for some messages.)
54       * @param messageKey   A key to the message which will appear on the question screen
55       * @param callback     A PurQuestionCallback
56       * @return An ActionForward
57       * @throws Exception
58       */
59      protected ActionForward askQuestionWithInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionType, String notePrefix, String operation, String messageKey, ReceivingQuestionCallback callback) throws Exception {
60          TreeMap<String, ReceivingQuestionCallback> questionsAndCallbacks = new TreeMap<String, ReceivingQuestionCallback>();
61          questionsAndCallbacks.put(questionType, callback);
62  
63          return askQuestionWithInput(mapping, form, request, response, questionType, notePrefix, operation, messageKey, questionsAndCallbacks, "", mapping.findForward(OLEConstants.MAPPING_BASIC));
64      }
65  
66      /**
67       * Builds and asks questions which require text input by the user for a payment request or a credit memo.
68       *
69       * @param mapping               An ActionMapping
70       * @param form                  An ActionForm
71       * @param request               The HttpServletRequest
72       * @param response              The HttpServletResponse
73       * @param questionType          A String used to distinguish which question is being asked
74       * @param notePrefix            A String explaining what action was taken, to be prepended to the note containing the reason, which gets
75       *                              written to the document
76       * @param operation             A one-word String description of the action to be taken, to be substituted into the message. (Can be an
77       *                              empty String for some messages.)
78       * @param messageKey            A (whole) key to the message which will appear on the question screen
79       * @param questionsAndCallbacks A TreeMap associating the type of question to be asked and the type of callback which should
80       *                              happen in that case
81       * @param messagePrefix         The most general part of a key to a message text to be retrieved from ConfigurationService,
82       *                              Describes a collection of questions.
83       * @param redirect              An ActionForward to return to if done with questions
84       * @return An ActionForward
85       * @throws Exception
86       */
87      protected ActionForward askQuestionWithInput(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionType, String notePrefix, String operation, String messageKey, TreeMap<String, ReceivingQuestionCallback> questionsAndCallbacks, String messagePrefix, ActionForward redirect) throws Exception {
88          KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
89          ReceivingDocument receivingDocument = (ReceivingDocument) kualiDocumentFormBase.getDocument();
90  
91          String question = (String) request.getParameter(OLEConstants.QUESTION_INST_ATTRIBUTE_NAME);
92          String reason = request.getParameter(OLEConstants.QUESTION_REASON_ATTRIBUTE_NAME);
93          String noteText = "";
94  
95          ConfigurationService kualiConfiguration = SpringContext.getBean(ConfigurationService.class);
96          String firstQuestion = questionsAndCallbacks.firstKey();
97          ReceivingQuestionCallback callback = null;
98          Iterator questions = questionsAndCallbacks.keySet().iterator();
99          String mapQuestion = null;
100         String key = null;
101 
102         // Start in logic for confirming the close.
103         if (question == null) {
104             key = getQuestionProperty(messageKey, messagePrefix, kualiConfiguration, firstQuestion);
105             String message = StringUtils.replace(key, "{0}", operation);
106 
107             // Ask question if not already asked.
108             return this.performQuestionWithInput(mapping, form, request, response, firstQuestion, message, OLEConstants.CONFIRMATION_QUESTION, questionType, "");
109         } else {
110             // find callback for this question
111             while (questions.hasNext()) {
112                 mapQuestion = (String) questions.next();
113 
114                 if (StringUtils.equals(mapQuestion, question)) {
115                     callback = questionsAndCallbacks.get(mapQuestion);
116                     break;
117                 }
118             }
119             key = getQuestionProperty(messageKey, messagePrefix, kualiConfiguration, mapQuestion);
120 
121             Object buttonClicked = request.getParameter(OLEConstants.QUESTION_CLICKED_BUTTON);
122             if (question.equals(mapQuestion) && buttonClicked.equals(ConfirmationQuestion.NO)) {
123                 // If 'No' is the button clicked, just reload the doc
124 
125                 String nextQuestion = null;
126                 // ask another question if more left
127                 if (questions.hasNext()) {
128                     nextQuestion = (String) questions.next();
129                     key = getQuestionProperty(messageKey, messagePrefix, kualiConfiguration, nextQuestion);
130 
131                     return this.performQuestionWithInput(mapping, form, request, response, nextQuestion, key, OLEConstants.CONFIRMATION_QUESTION, questionType, "");
132                 } else {
133 
134                     return mapping.findForward(OLEConstants.MAPPING_BASIC);
135                 }
136             }
137             // Have to check length on value entered.
138             String introNoteMessage = notePrefix + OLEConstants.BLANK_SPACE;
139 
140             // Build out full message.
141             noteText = introNoteMessage + reason;
142             int noteTextLength = noteText.length();
143 
144             // Get note text max length from DD.
145             int noteTextMaxLength = SpringContext.getBean(DataDictionaryService.class).getAttributeMaxLength(Note.class, OLEConstants.NOTE_TEXT_PROPERTY_NAME).intValue();
146             if (StringUtils.isBlank(reason) || (noteTextLength > noteTextMaxLength)) {
147                 // Figure out exact number of characters that the user can enter.
148                 int reasonLimit = noteTextMaxLength - noteTextLength;
149                 if (reason == null) {
150                     // Prevent a NPE by setting the reason to a blank string.
151                     reason = "";
152                 }
153 
154                 return this.performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, mapQuestion, key, OLEConstants.CONFIRMATION_QUESTION, questionType, "", reason, PurapKeyConstants.ERROR_PAYMENT_REQUEST_REASON_REQUIRED, OLEConstants.QUESTION_REASON_ATTRIBUTE_NAME, new Integer(reasonLimit).toString());
155             }
156         }
157 
158         // make callback
159         if (ObjectUtils.isNotNull(callback)) {
160             ReceivingDocument refreshedReceivingDocument = callback.doPostQuestion(receivingDocument, noteText);
161             kualiDocumentFormBase.setDocument(refreshedReceivingDocument);
162         }
163         String nextQuestion = null;
164         // ask another question if more left
165         if (questions.hasNext()) {
166             nextQuestion = (String) questions.next();
167             key = getQuestionProperty(messageKey, messagePrefix, kualiConfiguration, nextQuestion);
168 
169             return this.performQuestionWithInput(mapping, form, request, response, nextQuestion, key, OLEConstants.CONFIRMATION_QUESTION, questionType, "");
170         }
171 
172         return redirect;
173     }
174 
175     /**
176      * Used to look up messages to be displayed, from the ConfigurationService, given either a whole key or two parts of a key
177      * that may be concatenated together.
178      *
179      * @param messageKey         String. One of the message keys in PurapKeyConstants.
180      * @param messagePrefix      String. A prefix to the question key, such as "ap.question." that, concatenated with the question,
181      *                           comprises the whole key of the message.
182      * @param kualiConfiguration An instance of ConfigurationService
183      * @param question           String. The most specific part of the message key in PurapKeyConstants.
184      * @return The message to be displayed given the key
185      */
186     protected String getQuestionProperty(String messageKey, String messagePrefix, ConfigurationService kualiConfiguration, String question) {
187 
188         return kualiConfiguration.getPropertyValueAsString((StringUtils.isEmpty(messagePrefix)) ? messageKey : messagePrefix + question);
189     }
190 
191 }