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.module.purap.document.web.struts;
017
018 import java.io.ByteArrayOutputStream;
019 import java.sql.Date;
020 import java.util.ArrayList;
021 import java.util.Calendar;
022 import java.util.HashMap;
023 import java.util.List;
024 import java.util.Map;
025 import java.util.Properties;
026 import java.util.StringTokenizer;
027
028 import javax.servlet.ServletOutputStream;
029 import javax.servlet.http.HttpServletRequest;
030 import javax.servlet.http.HttpServletResponse;
031
032 import org.apache.commons.lang.StringUtils;
033 import org.apache.struts.action.ActionForm;
034 import org.apache.struts.action.ActionForward;
035 import org.apache.struts.action.ActionMapping;
036 import org.apache.struts.action.ActionMessage;
037 import org.apache.struts.action.ActionMessages;
038 import org.kuali.kfs.module.purap.PurapAuthorizationConstants;
039 import org.kuali.kfs.module.purap.PurapConstants;
040 import org.kuali.kfs.module.purap.PurapConstants.PODocumentsStrings;
041 import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderDocTypes;
042 import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses;
043 import org.kuali.kfs.module.purap.PurapKeyConstants;
044 import org.kuali.kfs.module.purap.PurapPropertyConstants;
045 import org.kuali.kfs.module.purap.SingleConfirmationQuestion;
046 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
047 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderQuoteList;
048 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderQuoteListVendor;
049 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderSensitiveData;
050 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorQuote;
051 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorStipulation;
052 import org.kuali.kfs.module.purap.businessobject.SensitiveData;
053 import org.kuali.kfs.module.purap.businessobject.SensitiveDataAssignment;
054 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
055 import org.kuali.kfs.module.purap.document.PurchaseOrderRetransmitDocument;
056 import org.kuali.kfs.module.purap.document.PurchaseOrderSplitDocument;
057 import org.kuali.kfs.module.purap.document.service.FaxService;
058 import org.kuali.kfs.module.purap.document.service.PurapService;
059 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService;
060 import org.kuali.kfs.module.purap.document.validation.event.AttributedAddVendorToQuoteEvent;
061 import org.kuali.kfs.module.purap.document.validation.event.AttributedAssignSensitiveDataEvent;
062 import org.kuali.kfs.module.purap.document.validation.event.AttributedSplitPurchaseOrderEvent;
063 import org.kuali.kfs.module.purap.service.SensitiveDataService;
064 import org.kuali.kfs.sys.KFSConstants;
065 import org.kuali.kfs.sys.KFSPropertyConstants;
066 import org.kuali.kfs.sys.context.SpringContext;
067 import org.kuali.kfs.vnd.VendorConstants.AddressTypes;
068 import org.kuali.kfs.vnd.businessobject.VendorAddress;
069 import org.kuali.kfs.vnd.businessobject.VendorDetail;
070 import org.kuali.kfs.vnd.document.service.VendorService;
071 import org.kuali.rice.kew.exception.WorkflowException;
072 import org.kuali.rice.kns.bo.Note;
073 import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
074 import org.kuali.rice.kns.exception.ValidationException;
075 import org.kuali.rice.kns.question.ConfirmationQuestion;
076 import org.kuali.rice.kns.service.BusinessObjectService;
077 import org.kuali.rice.kns.service.DataDictionaryService;
078 import org.kuali.rice.kns.service.DateTimeService;
079 import org.kuali.rice.kns.service.DictionaryValidationService;
080 import org.kuali.rice.kns.service.DocumentHelperService;
081 import org.kuali.rice.kns.service.DocumentService;
082 import org.kuali.rice.kns.service.KualiConfigurationService;
083 import org.kuali.rice.kns.service.KualiRuleService;
084 import org.kuali.rice.kns.util.GlobalVariables;
085 import org.kuali.rice.kns.util.ObjectUtils;
086 import org.kuali.rice.kns.util.UrlFactory;
087 import org.kuali.rice.kns.web.struts.form.BlankFormFile;
088 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
089 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
090
091 /**
092 * Struts Action for Purchase Order document.
093 */
094 public class PurchaseOrderAction extends PurchasingActionBase {
095 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderAction.class);
096
097 /**
098 * @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
099 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
100 */
101 @Override
102 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
103
104 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
105
106 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
107 BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
108
109 // Handling lookups for alternate vendor for non-primary vendor payment that are only specific to Purchase Order.
110 if (request.getParameter("document.alternateVendorHeaderGeneratedIdentifier") != null && request.getParameter("document.alternateVendorDetailAssignedIdentifier") != null) {
111 Integer alternateVendorDetailAssignedId = document.getAlternateVendorDetailAssignedIdentifier();
112 Integer alternateVendorHeaderGeneratedId = document.getAlternateVendorHeaderGeneratedIdentifier();
113 VendorDetail refreshVendorDetail = new VendorDetail();
114 refreshVendorDetail.setVendorDetailAssignedIdentifier(alternateVendorDetailAssignedId);
115 refreshVendorDetail.setVendorHeaderGeneratedIdentifier(alternateVendorHeaderGeneratedId);
116 refreshVendorDetail = (VendorDetail) businessObjectService.retrieve(refreshVendorDetail);
117 document.templateAlternateVendor(refreshVendorDetail);
118 }
119
120 // Handling lookups for quote list that is specific to Purchase Order.
121 if (request.getParameter("document.purchaseOrderQuoteListIdentifier") != null) {
122 // do a lookup and add all the vendors!
123 Integer poQuoteListIdentifier = document.getPurchaseOrderQuoteListIdentifier();
124 PurchaseOrderQuoteList poQuoteList = new PurchaseOrderQuoteList();
125 poQuoteList.setPurchaseOrderQuoteListIdentifier(poQuoteListIdentifier);
126 poQuoteList = (PurchaseOrderQuoteList) businessObjectService.retrieve(poQuoteList);
127 if (poQuoteList.isActive()) {
128 for (PurchaseOrderQuoteListVendor poQuoteListVendor : poQuoteList.getQuoteListVendors()) {
129 if ( poQuoteListVendor.isActive() ) {
130 VendorDetail newVendor = poQuoteListVendor.getVendorDetail();
131 if (newVendor.isActiveIndicator() && !newVendor.isVendorDebarred()) {
132 PurchaseOrderVendorQuote newPOVendorQuote = SpringContext.getBean(PurchaseOrderService.class).populateQuoteWithVendor(newVendor.getVendorHeaderGeneratedIdentifier(), newVendor.getVendorDetailAssignedIdentifier(), document.getDocumentNumber());
133 document.getPurchaseOrderVendorQuotes().add(newPOVendorQuote);
134 }
135 }
136 }
137 }
138 }
139
140 // Handling lookups for quote vendor search that is specific to Purchase Order.
141 String newVendorHeaderGeneratedIdentifier = request.getParameter("newPurchaseOrderVendorQuote.vendorHeaderGeneratedIdentifier");
142 String newVendorDetailAssignedIdentifier = request.getParameter("newPurchaseOrderVendorQuote.vendorDetailAssignedIdentifier");
143 if (newVendorHeaderGeneratedIdentifier != null && newVendorDetailAssignedIdentifier != null) {
144
145 PurchaseOrderVendorQuote newPOVendorQuote = SpringContext.getBean(PurchaseOrderService.class).populateQuoteWithVendor(new Integer(newVendorHeaderGeneratedIdentifier), new Integer(newVendorDetailAssignedIdentifier), document.getDocumentNumber());
146
147 poForm.setNewPurchaseOrderVendorQuote(newPOVendorQuote);
148 }
149
150 String newStipulation = request.getParameter(KFSPropertyConstants.DOCUMENT + "." + PurapPropertyConstants.VENDOR_STIPULATION_DESCRIPTION);
151 if (StringUtils.isNotEmpty(newStipulation)) {
152 poForm.getNewPurchaseOrderVendorStipulationLine().setVendorStipulationDescription(newStipulation);
153 }
154
155 return super.refresh(mapping, form, request, response);
156 }
157
158 /**
159 * Inactivate an item from the purchase order document.
160 *
161 * @param mapping An ActionMapping
162 * @param form An ActionForm
163 * @param request The HttpServletRequest
164 * @param response The HttpServletResponse
165 * @throws Exception
166 * @return An ActionForward
167 */
168 public ActionForward inactivateItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
169 PurchasingAccountsPayableFormBase purchasingForm = (PurchasingAccountsPayableFormBase) form;
170
171 PurchaseOrderDocument purDocument = (PurchaseOrderDocument) purchasingForm.getDocument();
172 PurchaseOrderItem item = (PurchaseOrderItem) purDocument.getItem(getSelectedLine(request));
173 item.setItemActiveIndicator(false);
174
175 return mapping.findForward(KFSConstants.MAPPING_BASIC);
176 }
177
178 /**
179 * For use with a specific set of methods of this class that create new purchase order-derived document types in response to
180 * user actions, including <code>closePo</code>, <code>reopenPo</code>, <code>paymentHoldPo</code>, <code>removeHoldPo</code>,
181 * <code>splitPo</code>, <code>amendPo</code>, and <code>voidPo</code>. It employs the question framework to ask
182 * the user for a response before creating and routing the new document. The response should consist of a note detailing a
183 * reason, and either yes or no. This method can be better understood if it is noted that it will be gone through twice (via the
184 * question framework); when each question is originally asked, and again when the yes/no response is processed, for
185 * confirmation.
186 *
187 * @param mapping These are boiler-plate.
188 * @param form "
189 * @param request "
190 * @param response "
191 * @param questionType A string identifying the type of question being asked.
192 * @param confirmType A string identifying which type of question is being confirmed.
193 * @param documentType A string, the type of document to create
194 * @param notePrefix A string to appear before the note in the BO Notes tab
195 * @param messageType A string to appear on the PO once the question framework is done, describing the action taken
196 * @param operation A string, the verb to insert in the original question describing the action to be taken
197 * @return An ActionForward
198 * @throws Exception
199 */
200 protected ActionForward askQuestionsAndPerformDocumentAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionType, String confirmType, String documentType, String notePrefix, String messageType, String operation) throws Exception {
201 LOG.debug("askQuestionsAndPerformDocumentAction started.");
202 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
203 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
204 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
205 String reason = request.getParameter(KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME);
206 String noteText = "";
207
208 try {
209 KualiConfigurationService kualiConfiguration = SpringContext.getBean(KualiConfigurationService.class);
210
211 // Start in logic for confirming the proposed operation.
212 if (ObjectUtils.isNull(question)) {
213 String message = "";
214 if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT)) {
215 message = kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_SPLIT_QUESTION_TEXT);
216 }
217 else {
218 String key = kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_DOCUMENT);
219 message = StringUtils.replace(key, "{0}", operation);
220 }
221 // Ask question if not already asked.
222 return this.performQuestionWithInput(mapping, form, request, response, questionType, message, KFSConstants.CONFIRMATION_QUESTION, questionType, "");
223 }
224 else {
225 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
226 if (question.equals(questionType) && buttonClicked.equals(ConfirmationQuestion.NO)) {
227
228 // If 'No' is the button clicked, just reload the doc
229 return returnToPreviousPage(mapping, kualiDocumentFormBase);
230 }
231 else if (question.equals(confirmType) && buttonClicked.equals(SingleConfirmationQuestion.OK)) {
232
233 // This is the case when the user clicks on "OK" in the end.
234 // After we inform the user that the close has been rerouted, we'll redirect to the portal page.
235 return mapping.findForward(KFSConstants.MAPPING_PORTAL);
236 }
237 else {
238 // Have to check length on value entered.
239 String introNoteMessage = notePrefix + KFSConstants.BLANK_SPACE;
240
241 // Build out full message.
242 noteText = introNoteMessage + reason;
243 int noteTextLength = noteText.length();
244
245 // Get note text max length from DD.
246 int noteTextMaxLength = SpringContext.getBean(DataDictionaryService.class).getAttributeMaxLength(Note.class, KFSConstants.NOTE_TEXT_PROPERTY_NAME).intValue();
247
248 if (StringUtils.isBlank(reason) || (noteTextLength > noteTextMaxLength)) {
249 // Figure out exact number of characters that the user can enter.
250 int reasonLimit = noteTextMaxLength - noteTextLength;
251
252 if (ObjectUtils.isNull(reason)) {
253 // Prevent a NPE by setting the reason to a blank string.
254 reason = "";
255 }
256
257 String message = "";
258 String key = kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_DOCUMENT);
259 message = StringUtils.replace(key, "{0}", operation);
260
261 return this.performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, questionType, message, KFSConstants.CONFIRMATION_QUESTION, questionType, "", reason, PurapKeyConstants.ERROR_PURCHASE_ORDER_REASON_REQUIRED, KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME, new Integer(reasonLimit).toString());
262 }
263 }
264 }
265 // Below used as a place holder to allow code to specify actionForward to return if not a 'success question'
266 ActionForward returnActionForward = null;
267 if (!po.isPendingActionIndicator()) {
268 /*
269 * Below if-else code block calls PurchaseOrderService methods that will throw ValidationException objects if errors
270 * occur during any process in the attempt to perform its actions. Assume, if these return successfully, that the
271 * PurchaseOrderDocument object returned from each is the newly created document and that all actions in the method
272 * were run correctly. NOTE: IF BELOW IF-ELSE IS EDITED THE NEW METHODS CALLED MUST THROW ValidationException OBJECT
273 * IF AN ERROR IS ADDED TO THE GlobalVariables
274 */
275 if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT)) {
276 po.setPendingSplit(true);
277 // Save adding the note for after the items are picked.
278 ((PurchaseOrderForm)kualiDocumentFormBase).setSplitNoteText(noteText);
279 returnActionForward = mapping.findForward(KFSConstants.MAPPING_BASIC);
280 }
281 else {
282 String newStatus = null;
283 if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT)) {
284 newStatus = PurchaseOrderStatuses.AMENDMENT;
285 po = SpringContext.getBean(PurchaseOrderService.class).createAndSavePotentialChangeDocument(kualiDocumentFormBase.getDocument().getDocumentNumber(), documentType, newStatus);
286 returnActionForward = mapping.findForward(KFSConstants.MAPPING_BASIC);
287 }
288 else {
289 if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT)) {
290 newStatus = PurchaseOrderStatuses.PENDING_CLOSE;
291 }
292 else if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT)) {
293 newStatus = PurchaseOrderStatuses.PENDING_REOPEN;
294 }
295 else if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_VOID_DOCUMENT)) {
296 newStatus = PurchaseOrderStatuses.PENDING_VOID;
297 }
298 else if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_PAYMENT_HOLD_DOCUMENT)) {
299 newStatus = PurchaseOrderStatuses.PENDING_PAYMENT_HOLD;
300 }
301 else if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REMOVE_HOLD_DOCUMENT)) {
302 newStatus = PurchaseOrderStatuses.PENDING_REMOVE_HOLD;
303 }
304 else if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_RETRANSMIT_DOCUMENT)) {
305 newStatus = PurchaseOrderStatuses.PENDING_RETRANSMIT;
306 }
307 po = SpringContext.getBean(PurchaseOrderService.class).createAndRoutePotentialChangeDocument(kualiDocumentFormBase.getDocument().getDocumentNumber(), documentType, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase), newStatus);
308 }
309 if (!GlobalVariables.getMessageMap().hasNoErrors()) {
310 throw new ValidationException("errors occurred during new PO creation");
311 }
312
313 String previousDocumentId = kualiDocumentFormBase.getDocId();
314 // Assume at this point document was created properly and 'po' variable is new PurchaseOrderDocument created
315 kualiDocumentFormBase.setDocument(po);
316 kualiDocumentFormBase.setDocId(po.getDocumentNumber());
317 kualiDocumentFormBase.setDocTypeName(po.getDocumentHeader().getWorkflowDocument().getDocumentType());
318
319 Note newNote = new Note();
320 if (documentType.equals(PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT)) {
321 noteText = noteText + " (Previous Document Id is " + previousDocumentId + ")";
322 }
323 newNote.setNoteText(noteText);
324 newNote.setNoteTypeCode(KFSConstants.NoteTypeEnum.BUSINESS_OBJECT_NOTE_TYPE.getCode());
325 kualiDocumentFormBase.setNewNote(newNote);
326
327 kualiDocumentFormBase.setAttachmentFile(new BlankFormFile());
328
329 insertBONote(mapping, kualiDocumentFormBase, request, response);
330 }
331 if (StringUtils.isNotEmpty(messageType)) {
332 GlobalVariables.getMessageList().add(messageType);
333 }
334 }
335 if (ObjectUtils.isNotNull(returnActionForward)) {
336 return returnActionForward;
337 }
338 else {
339
340 return this.performQuestionWithoutInput(mapping, form, request, response, confirmType, kualiConfiguration.getPropertyString(messageType), PODocumentsStrings.SINGLE_CONFIRMATION_QUESTION, questionType, "");
341 }
342 }
343 catch (ValidationException ve) {
344 throw ve;
345 }
346 }
347
348 /**
349 * Invoked when the user pressed on the Close Order button on a Purchase Order page to Close the PO. It will
350 * display the question page to the user to ask whether the user really wants to close the PO and ask the user to enter a reason
351 * in the text area. If the user has entered the reason, it will invoke a service method to do the processing for closing a PO,
352 * then display a Single Confirmation page to inform the user that the PO Close Document has been routed.
353 *
354 * @param mapping An ActionMapping
355 * @param form An ActionForm
356 * @param request The HttpServletRequest
357 * @param response The HttpServletResponse
358 * @throws Exception
359 * @return An ActionForward
360 */
361 public ActionForward closePo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
362 LOG.debug("ClosePO started.");
363 String operation = "Close ";
364 PurchaseOrderDocument po = ((PurchaseOrderForm)form).getPurchaseOrderDocument();
365
366 if (po.canClosePOForTradeIn()) {
367 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.CLOSE_QUESTION, PODocumentsStrings.CLOSE_CONFIRM, PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT, PODocumentsStrings.CLOSE_NOTE_PREFIX, PurapKeyConstants.PURCHASE_ORDER_MESSAGE_CLOSE_DOCUMENT, operation);
368 }
369 else {
370 return mapping.findForward(KFSConstants.MAPPING_BASIC);
371 }
372 }
373
374 /**
375 * Is invoked when the user pressed on the Payment Hold button on a Purchase Order page to put the PO on hold. It
376 * will display the question page to the user to ask whether the user really wants to put the PO on hold and ask the user to
377 * enter a reason in the text area. If the user has entered the reason, it will invoke a service method to do the processing for
378 * putting a PO on hold, then display a Single Confirmation page to inform the user that the PO Payment Hold Document has been
379 * routed.
380 *
381 * @param mapping An ActionMapping
382 * @param form An ActionForm
383 * @param request The HttpServletRequest
384 * @param response The HttpServletResponse
385 * @throws Exception
386 * @return An ActionForward
387 */
388 public ActionForward paymentHoldPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
389 LOG.debug("PaymentHoldPO started.");
390 String operation = "Hold Payment ";
391
392 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.PAYMENT_HOLD_QUESTION, PODocumentsStrings.PAYMENT_HOLD_CONFIRM, PurchaseOrderDocTypes.PURCHASE_ORDER_PAYMENT_HOLD_DOCUMENT, PODocumentsStrings.PAYMENT_HOLD_NOTE_PREFIX, PurapKeyConstants.PURCHASE_ORDER_MESSAGE_PAYMENT_HOLD, operation);
393 }
394
395 /**
396 * Is invoked when the user pressed on the Remove Hold button on a Payment Hold PO page to remove the PO from hold.
397 * It will display the question page to the user to ask whether the user really wants to remove the PO from hold and ask the
398 * user to enter a reason in the text area. If the user has entered the reason, it will invoke a service method to do the
399 * processing for removing a PO from hold, then display a Single Confirmation page to inform the user that the PO Remove Hold
400 * Document has been routed.
401 *
402 * @param mapping An ActionMapping
403 * @param form An ActionForm
404 * @param request The HttpServletRequest
405 * @param response The HttpServletResponse
406 * @throws Exception
407 * @return An ActionForward
408 */
409 public ActionForward removeHoldPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
410 LOG.debug("RemoveHoldPO started.");
411 String operation = "Remove Payment Hold ";
412 ActionForward forward = askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.REMOVE_HOLD_QUESTION, PODocumentsStrings.REMOVE_HOLD_CONFIRM, PurchaseOrderDocTypes.PURCHASE_ORDER_REMOVE_HOLD_DOCUMENT, PODocumentsStrings.REMOVE_HOLD_NOTE_PREFIX, PurapKeyConstants.PURCHASE_ORDER_MESSAGE_REMOVE_HOLD, operation);
413
414 return forward;
415 }
416
417 /**
418 * Is invoked when the user pressed on the Open Order button on a Purchase Order page that has status "Close" to
419 * reopen the PO. It will display the question page to the user to ask whether the user really wants to reopen the PO and ask
420 * the user to enter a reason in the text area. If the user has entered the reason, it will invoke the a service method to do
421 * the processing for reopening a PO, then display a Single Confirmation page to inform the user that the
422 * <code>PurchaseOrderReopenDocument</code> has been routed.
423 *
424 * @param mapping An ActionMapping
425 * @param form An ActionForm
426 * @param request The HttpServletRequest
427 * @param response The HttpServletResponse
428 * @throws Exception
429 * @return An ActionForward
430 * @see org.kuali.kfs.module.purap.document.PurchaseOrderReopenDocument
431 */
432 public ActionForward reopenPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
433 LOG.debug("Reopen PO started");
434 String operation = "Reopen ";
435
436 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.REOPEN_PO_QUESTION, PODocumentsStrings.CONFIRM_REOPEN_QUESTION, PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT, PODocumentsStrings.REOPEN_NOTE_PREFIX, PurapKeyConstants.PURCHASE_ORDER_MESSAGE_REOPEN_DOCUMENT, operation);
437 }
438
439 /**
440 * Is invoked when the user pressed on the Amend button on a Purchase Order page to amend the PO. It will display
441 * the question page to the user to ask whether the user really wants to amend the PO and ask the user to enter a reason in the
442 * text area. If the user has entered the reason, it will invoke a service method to do the processing for amending the PO, then
443 * display a Single Confirmation page to inform the user that the <code>PurchaseOrderAmendmentDocument</code> has been routed.
444 *
445 * @param mapping An ActionMapping
446 * @param form An ActionForm
447 * @param request The HttpServletRequest
448 * @param response The HttpServletResponse
449 * @throws Exception
450 * @return An ActionForward
451 * @see org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument
452 */
453 public ActionForward amendPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
454 LOG.debug("Amend PO started");
455 String operation = "Amend ";
456
457 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.AMENDMENT_PO_QUESTION, PODocumentsStrings.CONFIRM_AMENDMENT_QUESTION, PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT, PODocumentsStrings.AMENDMENT_NOTE_PREFIX, null, operation);
458 }
459
460 /**
461 * Is invoked when the user pressed on the Void button on a Purchase Order page to void the PO. It will display the
462 * question page to the user to ask whether the user really wants to void the PO and ask the user to enter a reason in the text
463 * area. If the user has entered the reason, it will invoke a service method to do the processing for voiding the PO, then
464 * display a Single Confirmation page to inform the user that the <code>PurchaseOrderVoidDocument</code> has been routed.
465 *
466 * @param mapping An ActionMapping
467 * @param form An ActionForm
468 * @param request The HttpServletRequest
469 * @param response The HttpServletResponse
470 * @throws Exception
471 * @return An ActionForward
472 * @see org.kuali.kfs.module.purap.document.PurchaseOrderVoidDocument
473 */
474 public ActionForward voidPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
475 LOG.debug("Void PO started");
476 String operation = "Void ";
477
478 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.VOID_QUESTION, PODocumentsStrings.VOID_CONFIRM, PurchaseOrderDocTypes.PURCHASE_ORDER_VOID_DOCUMENT, PODocumentsStrings.VOID_NOTE_PREFIX, PurapKeyConstants.PURCHASE_ORDER_MESSAGE_VOID_DOCUMENT, operation);
479 }
480
481 /**
482 * Invoked to initiate the splitting of a Purchase Order. Displays a question page to ask for a reason and confirmation
483 * of the user's desire to split the Purchase Order, and, if confirmed, a page on which the Split PO tab only is showing,
484 * and the items to move to the new PO are chosen. If that is done, and the user continues, a new Split Purchase Order document
485 * will be created, with the chosen items. That same set of items will be deleted from the original Purchase Order.
486 *
487 * @param mapping An ActionMapping
488 * @param form An ActionForm
489 * @param request The HttpServeletRequest
490 * @param response The HttpServeletResponse
491 * @return An ActionForward
492 * @throws Exception
493 * @see org.kuali.kfs.module.purap.document.PurchaseOrderSplitDocument
494 */
495 public ActionForward splitPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
496 LOG.debug("Split PO started");
497 String operation = "Split ";
498
499 return askQuestionsAndPerformDocumentAction(mapping, form, request, response, PODocumentsStrings.SPLIT_QUESTION, PODocumentsStrings.SPLIT_CONFIRM, PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT,PODocumentsStrings.SPLIT_NOTE_PREFIX_OLD_DOC,PurapKeyConstants.PURCHASE_ORDER_MESSAGE_SPLIT_DOCUMENT,operation);
500 }
501
502 /**
503 * Invoked when only the Split Purchase Order tab is showing to continue the process of splitting the PO, once items are chosen
504 * to be moved to the new PO.
505 *
506 * @param mapping An ActionMapping
507 * @param form An ActionForm
508 * @param request The HttpServeletRequest
509 * @param response The HttpServeletResponse
510 * @return An ActionForward
511 * @throws Exception
512 */
513 public ActionForward continuePurchaseOrderSplit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
514 LOG.debug("Continue Purchase Order Split started");
515
516 PurchaseOrderForm purchaseOrderForm = (PurchaseOrderForm) form;
517 // This PO does not contain all data, but enough for our purposes; it has been reloaded with only the Split PO tab showing.
518 PurchaseOrderDocument poToSplit = (PurchaseOrderDocument)purchaseOrderForm.getDocument();
519 boolean copyNotes = poToSplit.isCopyingNotesWhenSplitting();
520
521 // Check business rules before splitting.
522
523 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedSplitPurchaseOrderEvent(poToSplit));
524 if (!rulePassed) {
525 poToSplit.setPendingSplit(true);
526 }
527 else {
528 HashMap<String, List<PurchaseOrderItem>> categorizedItems = SpringContext.getBean(PurchaseOrderService.class).categorizeItemsForSplit((List<PurchaseOrderItem>)poToSplit.getItems());
529 List<PurchaseOrderItem> movingPOItems = categorizedItems.get(PODocumentsStrings.ITEMS_MOVING_TO_SPLIT);
530 List<PurchaseOrderItem> remainingPOItems = categorizedItems.get(PODocumentsStrings.ITEMS_REMAINING);
531
532 // Fetch the whole PO from the database, and reset and renumber the items on it.
533 poToSplit = (PurchaseOrderDocument)SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(poToSplit.getPurapDocumentIdentifier());
534 poToSplit.setItems(remainingPOItems);
535 poToSplit.renumberItems(0);
536
537 // Add the note that would normally have gone in after the confirmation page.
538 String noteText = purchaseOrderForm.getSplitNoteText();
539 try {
540 Note splitNote = SpringContext.getBean(DocumentService.class).createNoteFromDocument(poToSplit, noteText);
541 poToSplit.addNote(splitNote);
542 } catch ( Exception e ) {
543 throw new RuntimeException(e);
544 }
545 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(poToSplit);
546
547 PurchaseOrderSplitDocument splitPO = SpringContext.getBean(PurchaseOrderService.class).createAndSavePurchaseOrderSplitDocument(movingPOItems, poToSplit, copyNotes, noteText);
548
549 purchaseOrderForm.setDocument(splitPO);
550 purchaseOrderForm.setDocId(splitPO.getDocumentNumber());
551 purchaseOrderForm.setDocTypeName(splitPO.getDocumentHeader().getWorkflowDocument().getDocumentType());
552 try {
553 loadDocument(purchaseOrderForm);
554 }
555 catch (WorkflowException we) {
556 throw new RuntimeException(we);
557 }
558 }
559
560 return mapping.findForward(KFSConstants.MAPPING_BASIC);
561 }
562
563 /**
564 * Invoked from the page on which the Split PO tab is showing to cancel the splitting of the PO and return it to its original state.
565 *
566 * @param mapping An ActionMapping
567 * @param form An ActionForm
568 * @param request The HttpServeletRequest
569 * @param response The HttpServeletResponse
570 * @return An ActionForward
571 * @throws Exception
572 */
573 public ActionForward cancelPurchaseOrderSplit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
574 LOG.debug("Cancel Purchase Order Split started");
575
576 PurchaseOrderForm purchaseOrderForm = (PurchaseOrderForm)form;
577 PurchaseOrderDocument po = (PurchaseOrderDocument)purchaseOrderForm.getDocument();
578
579 po = SpringContext.getBean(PurchaseOrderService.class).getPurchaseOrderByDocumentNumber(po.getDocumentNumber());
580
581 po.setPendingSplit(false);
582 po.setCopyingNotesWhenSplitting(false);
583 purchaseOrderForm.setDocument(po);
584 reload(mapping, purchaseOrderForm, request, response);
585
586 return mapping.findForward(KFSConstants.MAPPING_BASIC);
587 }
588
589 /**
590 * Invoked when an authorized user presses "Sensitive Data" button on the purchase order page.
591 *
592 * @param mapping An ActionMapping
593 * @param form An ActionForm
594 * @param request The HttpServeletRequest
595 * @param response The HttpServeletResponse
596 * @return An ActionForward
597 * @throws Exception
598 */
599 public ActionForward assignSensitiveData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
600 LOG.debug("Assign Sensitive Data started");
601
602 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
603 PurchaseOrderDocument po = (PurchaseOrderDocument)poForm.getDocument();
604 Integer poId = po.getPurapDocumentIdentifier();
605 SensitiveDataService sdService = SpringContext.getBean(SensitiveDataService.class);
606
607 // set the assignment flag and reset input fields
608 po.setAssigningSensitiveData(true);
609 poForm.setSensitiveDataAssignmentReason("");
610 poForm.setNewSensitiveDataLine(new SensitiveData());
611
612 // load previous assignment info
613 SensitiveDataAssignment sda = sdService.getLastSensitiveDataAssignment(poId);
614 poForm.setLastSensitiveDataAssignment(sda);
615
616 // even though at this point, the sensitive data entries should have been loaded into the form already,
617 // we still load them again in case that someone else has changed that during the time period
618 List<SensitiveData> posds = sdService.getSensitiveDatasAssignedByPoId(poId);
619 poForm.setSensitiveDatasAssigned(posds);
620
621 return mapping.findForward(KFSConstants.MAPPING_BASIC);
622 }
623
624 /**
625 * Invoked when an authorized user presses "Submit" button on the "Assign Sensitive Data" page.
626 *
627 * @param mapping An ActionMapping
628 * @param form An ActionForm
629 * @param request The HttpServeletRequest
630 * @param response The HttpServeletResponse
631 * @return An ActionForward
632 * @throws Exception
633 */
634 public ActionForward submitSensitiveData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
635 LOG.debug("Submit Sensitive Data started");
636
637 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
638 PurchaseOrderDocument po = (PurchaseOrderDocument)poForm.getDocument();
639 Integer poId = po.getPurapDocumentIdentifier();
640 List<SensitiveData> sds = poForm.getSensitiveDatasAssigned();
641 String sdaReason = poForm.getSensitiveDataAssignmentReason();
642 SensitiveDataService sdService = SpringContext.getBean(SensitiveDataService.class);
643
644 // check business rules
645 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedAssignSensitiveDataEvent("", po, sdaReason, sds));
646 if (!rulePassed) {
647 return mapping.findForward(KFSConstants.MAPPING_BASIC);
648 }
649
650 // update table SensitiveDataAssignment
651 SensitiveDataAssignment sda = new SensitiveDataAssignment(poId, poForm.getSensitiveDataAssignmentReason(), GlobalVariables.getUserSession().getPerson().getPrincipalName(), poForm.getSensitiveDatasAssigned());
652 SpringContext.getBean(BusinessObjectService.class).save(sda);
653
654 // update table PurchaseOrderSensitiveData
655 sdService.deletePurchaseOrderSensitiveDatas(poId);
656 List<PurchaseOrderSensitiveData> posds = new ArrayList<PurchaseOrderSensitiveData>();
657 for (SensitiveData sd : sds) {
658 posds.add(new PurchaseOrderSensitiveData(poId, po.getRequisitionIdentifier(), sd.getSensitiveDataCode()));
659 }
660 SpringContext.getBean(BusinessObjectService.class).save(posds);
661
662 // need this to update workflow doc for searching restrictions on sensitive data
663 SpringContext.getBean(PurapService.class).saveRoutingDataForRelatedDocuments(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
664
665 // reset the sensitive data related fields in the po form
666 po.setAssigningSensitiveData(false);
667
668 return mapping.findForward(KFSConstants.MAPPING_BASIC);
669 }
670
671 /**
672 * Invoked when an authorized user presses "Cancel" button on the "Assign Sensitive Data" page.
673 *
674 * @param mapping An ActionMapping
675 * @param form An ActionForm
676 * @param request The HttpServeletRequest
677 * @param response The HttpServeletResponse
678 * @return An ActionForward
679 * @throws Exception
680 */
681 public ActionForward cancelSensitiveData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
682 LOG.debug("Cancel Sensitive Data started");
683
684 // reset the sensitive data flag in the po form, reload sensitive data from database to undo the canceled changes
685 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
686 PurchaseOrderDocument po = (PurchaseOrderDocument)poForm.getDocument();
687 po.setAssigningSensitiveData(false);
688 List<SensitiveData> sds = SpringContext.getBean(SensitiveDataService.class).getSensitiveDatasAssignedByPoId(po.getPurapDocumentIdentifier());
689 poForm.setSensitiveDatasAssigned(sds);
690
691 return mapping.findForward(KFSConstants.MAPPING_BASIC);
692 }
693
694 /**
695 * Invoked when an authorized user presses "Add" button on the "Assign Sensitive Data" page.
696 *
697 * @param mapping An ActionMapping
698 * @param form An ActionForm
699 * @param request The HttpServeletRequest
700 * @param response The HttpServeletResponse
701 * @return An ActionForward
702 * @throws Exception
703 */
704 public ActionForward addSensitiveData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
705 LOG.debug("Add Sensitive Data started");
706
707 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
708 SensitiveDataService sdService = SpringContext.getBean(SensitiveDataService.class);
709
710 // retrieve new sensitive data by code, add the new line
711 SensitiveData newsd = poForm.getNewSensitiveDataLine();
712 newsd = sdService.getSensitiveDataByCode(newsd.getSensitiveDataCode());
713 List<SensitiveData> sds = poForm.getSensitiveDatasAssigned();
714 sds.add(newsd);
715
716 // reset new line
717 poForm.setNewSensitiveDataLine(new SensitiveData());
718
719 return mapping.findForward(KFSConstants.MAPPING_BASIC);
720 }
721
722 /**
723 * Invoked when an authorized user presses "Delete" button on the "Assign Sensitive Data" page.
724 *
725 * @param mapping An ActionMapping
726 * @param form An ActionForm
727 * @param request The HttpServeletRequest
728 * @param response The HttpServeletResponse
729 * @return An ActionForward
730 * @throws Exception
731 */
732 public ActionForward deleteSensitiveData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
733 LOG.debug("Delete Sensitive Data started");
734
735 // remove the selected sensitive data line
736 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
737 List<SensitiveData> sds = poForm.getSensitiveDatasAssigned();
738 sds.remove(getSelectedLine(request));
739
740 return mapping.findForward(KFSConstants.MAPPING_BASIC);
741 }
742
743 /**
744 * This is a utility method used to prepare to and to return to a previous page, making sure that the buttons will be restored
745 * in the process.
746 *
747 * @param kualiDocumentFormBase The Form, considered as a KualiDocumentFormBase, as it typically is here.
748 * @return An actionForward mapping back to the original page.
749 */
750 protected ActionForward returnToPreviousPage(ActionMapping mapping, KualiDocumentFormBase kualiDocumentFormBase) {
751
752 return mapping.findForward(KFSConstants.MAPPING_BASIC);
753 }
754
755 /**
756 * Is executed when the user clicks on the "print" button on a Purchase Order Print Document page. On a non
757 * javascript enabled browser, it will display a page with 2 buttons. One is to display the PDF, the other is to view the PO
758 * tabbed page where the PO document statuses, buttons, etc have already been updated (the updates of those occurred while the
759 * <code>performPurchaseOrderFirstTransmitViaPrinting</code> method is invoked. On a javascript enabled browser, it will
760 * display both the PO tabbed page containing the updated PO document info and the pdf on the next window/tab of the browser.
761 *
762 * @param mapping An ActionMapping
763 * @param form An ActionForm
764 * @param request The HttpServletRequest
765 * @param response The HttpServletResponse
766 * @throws Exception
767 * @return An ActionForward
768 */
769 public ActionForward firstTransmitPrintPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
770 String poDocId = ((PurchaseOrderForm)form).getDocId();
771 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
772 try {
773 SpringContext.getBean(PurchaseOrderService.class).performPurchaseOrderFirstTransmitViaPrinting(poDocId, baosPDF);
774 }
775 finally {
776 if (baosPDF != null) {
777 baosPDF.reset();
778 }
779 }
780 String basePath = getBasePath(request);
781 String docId = ((PurchaseOrderForm) form).getDocId();
782 String methodToCallPrintPurchaseOrderPDF = "printPurchaseOrderPDFOnly";
783 String methodToCallDocHandler = "docHandler";
784 String printPOPDFUrl = getUrlForPrintPO(basePath, docId, methodToCallPrintPurchaseOrderPDF);
785 String displayPOTabbedPageUrl = getUrlForPrintPO(basePath, docId, methodToCallDocHandler);
786 request.setAttribute("printPOPDFUrl", printPOPDFUrl);
787 request.setAttribute("displayPOTabbedPageUrl", displayPOTabbedPageUrl);
788 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER);
789 request.setAttribute("purchaseOrderLabel", label);
790
791 return mapping.findForward("printPurchaseOrderPDF");
792 }
793
794 /**
795 * Creates a URL to be used in printing the purchase order.
796 *
797 * @param basePath String: The base path of the current URL
798 * @param docId String: The document ID of the document to be printed
799 * @param methodToCall String: The name of the method that will be invoked to do this particular print
800 * @return The URL
801 */
802 protected String getUrlForPrintPO(String basePath, String docId, String methodToCall) {
803 StringBuffer result = new StringBuffer(basePath);
804 result.append("/purapPurchaseOrder.do?methodToCall=");
805 result.append(methodToCall);
806 result.append("&docId=");
807 result.append(docId);
808 result.append("&command=displayDocSearchView");
809
810 return result.toString();
811 }
812
813 /**
814 * Prints the PDF only, as opposed to <code>firstTransmitPrintPo</code>, which calls this method (indirectly) to print the
815 * PDF, and calls the doc handler to display the PO tabbed page.
816 *
817 * @param mapping An ActionMapping
818 * @param form An ActionForm
819 * @param request The HttpServletRequest
820 * @param response The HttpServletResponse
821 * @throws Exception
822 * @return An ActionForward
823 */
824 public ActionForward printPurchaseOrderPDFOnly(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
825 String poDocId = request.getParameter("docId");
826 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
827 try {
828 // will throw validation exception if errors occur
829 SpringContext.getBean(PurchaseOrderService.class).performPrintPurchaseOrderPDFOnly(poDocId, baosPDF);
830
831 response.setHeader("Cache-Control", "max-age=30");
832 response.setContentType("application/pdf");
833 StringBuffer sbContentDispValue = new StringBuffer();
834 String useJavascript = request.getParameter("useJavascript");
835 if (useJavascript == null || useJavascript.equalsIgnoreCase("false")) {
836 sbContentDispValue.append("attachment");
837 }
838 else {
839 sbContentDispValue.append("inline");
840 }
841 StringBuffer sbFilename = new StringBuffer();
842 sbFilename.append("PURAP_PO_");
843 sbFilename.append(poDocId);
844 sbFilename.append("_");
845 sbFilename.append(System.currentTimeMillis());
846 sbFilename.append(".pdf");
847 sbContentDispValue.append("; filename=");
848 sbContentDispValue.append(sbFilename);
849
850 response.setHeader("Content-disposition", sbContentDispValue.toString());
851
852 response.setContentLength(baosPDF.size());
853
854 ServletOutputStream sos;
855
856 sos = response.getOutputStream();
857
858 baosPDF.writeTo(sos);
859
860 sos.flush();
861
862 }
863 finally {
864 if (baosPDF != null) {
865 baosPDF.reset();
866 }
867 }
868
869 return null;
870 }
871
872 /**
873 * Print a particular selected PO Quote as a PDF.
874 *
875 * @param mapping An ActionMapping
876 * @param form An ActionForm -- The PO Quote must be selected here.
877 * @param request The HttpServletRequest
878 * @param response The HttpServletResponse
879 * @throws Exception
880 * @return An ActionForward
881 */
882 public ActionForward printPoQuote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
883 // String poDocId = request.getParameter("docId");
884 // PurchaseOrderDocument po = (PurchaseOrderDocument)
885 // SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(poDocId);
886 // Integer poSelectedVendorId = new Integer(request.getParameter("quoteVendorId"));
887 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
888 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
889 PurchaseOrderVendorQuote poVendorQuote = po.getPurchaseOrderVendorQuotes().get(getSelectedLine(request));
890 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
891 poVendorQuote.setTransmitPrintDisplayed(false);
892 try {
893 StringBuffer sbFilename = new StringBuffer();
894 sbFilename.append("PURAP_PO_QUOTE_");
895 sbFilename.append(po.getPurapDocumentIdentifier());
896 sbFilename.append("_");
897 sbFilename.append(System.currentTimeMillis());
898 sbFilename.append(".pdf");
899
900 boolean success = SpringContext.getBean(PurchaseOrderService.class).printPurchaseOrderQuotePDF(po, poVendorQuote, baosPDF);
901
902 if (!success) {
903 poVendorQuote.setTransmitPrintDisplayed(true);
904 poVendorQuote.setPdfDisplayedToUserOnce(false);
905
906 if (baosPDF != null) {
907 baosPDF.reset();
908 }
909 return mapping.findForward(KFSConstants.MAPPING_BASIC);
910 }
911 response.setHeader("Cache-Control", "max-age=30");
912 response.setContentType("application/pdf");
913 StringBuffer sbContentDispValue = new StringBuffer();
914 // sbContentDispValue.append("inline");
915 sbContentDispValue.append("attachment");
916 sbContentDispValue.append("; filename=");
917 sbContentDispValue.append(sbFilename);
918
919 response.setHeader("Content-disposition", sbContentDispValue.toString());
920
921 response.setContentLength(baosPDF.size());
922
923 ServletOutputStream sos;
924
925 sos = response.getOutputStream();
926
927 baosPDF.writeTo(sos);
928
929 sos.flush();
930
931 }
932 finally {
933 if (baosPDF != null) {
934 baosPDF.reset();
935 }
936 }
937
938 return null;
939 }
940
941 public ActionForward printPoQuoteList(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
942 String poDocId = ((PurchaseOrderForm)form).getDocId();
943 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
944 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
945 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(po);
946 String basePath = getBasePath(request);
947 String methodToCallPrintPurchaseOrderPDF = "printPoQuoteListOnly";
948 String methodToCallDocHandler = "docHandler";
949 String printPOQuoteListPDFUrl = getUrlForPrintPO(basePath, poDocId, methodToCallPrintPurchaseOrderPDF);
950 String displayPOTabbedPageUrl = getUrlForPrintPO(basePath, poDocId, methodToCallDocHandler);
951 request.setAttribute("printPOQuoteListPDFUrl", printPOQuoteListPDFUrl);
952 request.setAttribute("displayPOTabbedPageUrl", displayPOTabbedPageUrl);
953 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER);
954 request.setAttribute("purchaseOrderLabel", label);
955
956 return mapping.findForward("printPOQuoteListPDF");
957 }
958
959 /**
960 * Print the list of PO Quote requests.
961 *
962 * @param mapping An ActionMapping
963 * @param form An ActionForm
964 * @param request The HttpServletRequest
965 * @param response The HttpServletResponse
966 * @throws Exception
967 * @return An ActionForward
968 */
969 public ActionForward printPoQuoteListOnly(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
970 String poDocId = request.getParameter("docId");
971 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
972 try {
973 StringBuffer sbFilename = new StringBuffer();
974 sbFilename.append("PURAP_PO_QUOTE_LIST_");
975 sbFilename.append(poDocId);
976 sbFilename.append("_");
977 sbFilename.append(System.currentTimeMillis());
978 sbFilename.append(".pdf");
979
980 boolean success = SpringContext.getBean(PurchaseOrderService.class).printPurchaseOrderQuoteRequestsListPDF(poDocId, baosPDF);
981
982 if (!success) {
983 if (baosPDF != null) {
984 baosPDF.reset();
985 }
986 return mapping.findForward(KFSConstants.MAPPING_PORTAL);
987 }
988 response.setHeader("Cache-Control", "max-age=30");
989 response.setContentType("application/pdf");
990 StringBuffer sbContentDispValue = new StringBuffer();
991 String useJavascript = request.getParameter("useJavascript");
992 if (useJavascript == null || useJavascript.equalsIgnoreCase("false")) {
993 sbContentDispValue.append("attachment");
994 }
995 else {
996 sbContentDispValue.append("inline");
997 }
998 sbContentDispValue.append("; filename=");
999 sbContentDispValue.append(sbFilename);
1000
1001 response.setHeader("Content-disposition", sbContentDispValue.toString());
1002
1003 response.setContentLength(baosPDF.size());
1004
1005 ServletOutputStream sos;
1006
1007 sos = response.getOutputStream();
1008
1009 baosPDF.writeTo(sos);
1010
1011 sos.flush();
1012
1013 }
1014 finally {
1015 if (baosPDF != null) {
1016 baosPDF.reset();
1017 }
1018 }
1019
1020 return null;
1021 }
1022
1023 /**
1024 * Initiates transmission of a PO Quote request.
1025 *
1026 * @param mapping An ActionMapping
1027 * @param form An ActionForm
1028 * @param request The HttpServletRequest
1029 * @param response The HttpServletResponse
1030 * @throws Exception
1031 * @return An ActionForward
1032 */
1033 public ActionForward transmitPurchaseOrderQuote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1034 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1035 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1036 PurchaseOrderVendorQuote vendorQuote = (PurchaseOrderVendorQuote) po.getPurchaseOrderVendorQuotes().get(getSelectedLine(request));
1037 if (PurapConstants.QuoteTransmitTypes.PRINT.equals(vendorQuote.getPurchaseOrderQuoteTransmitTypeCode())) {
1038 vendorQuote.setPurchaseOrderQuoteTransmitTimestamp(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp());
1039 vendorQuote.setTransmitPrintDisplayed(true);
1040 vendorQuote.setPdfDisplayedToUserOnce(false);
1041 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(po);
1042 }
1043 else if (PurapConstants.QuoteTransmitTypes.FAX.equals(vendorQuote.getPurchaseOrderQuoteTransmitTypeCode())) {
1044 // call fax service
1045 GlobalVariables.getMessageMap().clear();
1046 FaxService faxService = SpringContext.getBean(FaxService.class);
1047 faxService.faxPurchaseOrderPdf(po, false);
1048 if (GlobalVariables.getMessageMap().size() == 0) {
1049 vendorQuote.setPurchaseOrderQuoteTransmitTimestamp(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp());
1050 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(po);
1051 }
1052 }
1053 else {
1054 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_TRANSMIT_TYPE_NOT_SELECTED);
1055 }
1056
1057 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1058 }
1059
1060 /**
1061 * Is invoked when the user clicks on the Select All button on a Purchase Order Retransmit document. It will select
1062 * the checkboxes of all the items to be included in the retransmission of the PO.
1063 *
1064 * @param mapping An ActionMapping
1065 * @param form An ActionForm
1066 * @param request The HttpServletRequest
1067 * @param response The HttpServletResponse
1068 * @throws Exception
1069 * @return An ActionForward
1070 */
1071 public ActionForward selectAllForRetransmit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1072 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1073 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1074 List<PurchaseOrderItem> items = po.getItems();
1075 for (PurchaseOrderItem item : items) {
1076 item.setItemSelectedForRetransmitIndicator(true);
1077 }
1078
1079 return returnToPreviousPage(mapping, kualiDocumentFormBase);
1080 }
1081
1082 /**
1083 * Is invoked when the user clicks on the Deselect All button on a Purchase Order Retransmit document. It will
1084 * uncheck the checkboxes of all the items to be excluded from the retransmission of the PO.
1085 *
1086 * @param mapping An ActionMapping
1087 * @param form An ActionForm
1088 * @param request The HttpServletRequest
1089 * @param response The HttpServletResponse
1090 * @throws Exception
1091 * @return An ActionForward
1092 */
1093 public ActionForward deselectAllForRetransmit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1094 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1095 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1096 List<PurchaseOrderItem> items = po.getItems();
1097 for (PurchaseOrderItem item : items) {
1098 item.setItemSelectedForRetransmitIndicator(false);
1099 }
1100
1101 return returnToPreviousPage(mapping, kualiDocumentFormBase);
1102 }
1103
1104 /**
1105 * Is invoked when the user clicks on the Retransmit button on both the PO tabbed page and on the Purchase Order
1106 * Retransmit Document page, which is essentially a PO tabbed page with the other irrelevant tabs being hidden. If it was
1107 * invoked from the PO tabbed page, if the PO's pending indicator is false, this method will invoke a method in the
1108 * PurchaseOrderService to update the flags, create the PurchaseOrderRetransmitDocument and route it. If the routing was
1109 * successful, we'll display the Purchase Order Retransmit Document page to the user, containing the newly created and routed
1110 * PurchaseOrderRetransmitDocument and a retransmit button as well as a list of items that the user can select to be
1111 * retransmitted. If it was invoked from the Purchase Order Retransmit Document page, we'll invoke the
1112 * retransmitPurchaseOrderPDF method to create a PDF document based on the PO information and the items that were selected by
1113 * the user on the Purchase Order Retransmit Document page to be retransmitted, then display the PDF to the browser.
1114 *
1115 * @param mapping An ActionMapping
1116 * @param form An ActionForm
1117 * @param request The HttpServletRequest
1118 * @param response The HttpServletResponse
1119 * @throws Exception
1120 * @return An ActionForward
1121 */
1122 public ActionForward retransmitPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1123 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1124 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1125
1126 boolean success;
1127 if (po.isPendingActionIndicator()) {
1128 success = false;
1129 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_PURCHASE_ORDER_IS_PENDING);
1130 }
1131 else {
1132 po = SpringContext.getBean(PurchaseOrderService.class).createAndRoutePotentialChangeDocument(kualiDocumentFormBase.getDocument().getDocumentNumber(), PurchaseOrderDocTypes.PURCHASE_ORDER_RETRANSMIT_DOCUMENT, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase), PurchaseOrderStatuses.PENDING_RETRANSMIT);
1133 ((PurchaseOrderRetransmitDocument)po).setShouldDisplayRetransmitTab(true);
1134 }
1135
1136 kualiDocumentFormBase.setDocument(po);
1137 // we only need to set the editing mode to displayRetransmitTab if it's not yet
1138 // in the editingMode.
1139 if (!kualiDocumentFormBase.getEditingMode().containsKey(PurapAuthorizationConstants.PurchaseOrderEditMode.DISPLAY_RETRANSMIT_TAB)) {
1140 DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(po);
1141 // TODO this method is gone, fix for kim
1142 // kualiDocumentFormBase.populateAuthorizationFields(documentAuthorizer);
1143 }
1144
1145 return returnToPreviousPage(mapping, kualiDocumentFormBase);
1146 }
1147
1148
1149 /**
1150 * Is invoked when the user clicks on the Retransmit button on both the PO tabbed page and on the Purchase Order
1151 * Retransmit Document page, which is essentially a PO tabbed page with the other irrelevant tabs being hidden. If it was
1152 * invoked from the PO tabbed page, if the PO's pending indicator is false, this method will invoke a method in the
1153 * PurchaseOrderService to update the flags, create the PurchaseOrderRetransmitDocument and route it. If the routing was
1154 * successful, we'll display the Purchase Order Retransmit Document page to the user, containing the newly created and routed
1155 * PurchaseOrderRetransmitDocument and a retransmit button as well as a list of items that the user can select to be
1156 * retransmitted. If it was invoked from the Purchase Order Retransmit Document page, we'll invoke the
1157 * retransmitPurchaseOrderPDF method to create a PDF document based on the PO information and the items that were selected by
1158 * the user on the Purchase Order Retransmit Document page to be retransmitted, then display the PDF to the browser.
1159 *
1160 * @param mapping An ActionMapping
1161 * @param form An ActionForm
1162 * @param request The HttpServletRequest
1163 * @param response The HttpServletResponse
1164 * @throws Exception
1165 * @return An ActionForward
1166 */
1167 public ActionForward printingPreviewPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1168 String poDocId = ((PurchaseOrderForm)form).getDocId();
1169 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
1170 try {
1171 SpringContext.getBean(PurchaseOrderService.class).performPurchaseOrderPreviewPrinting(poDocId, baosPDF);
1172 }
1173 finally {
1174 if (baosPDF != null) {
1175 baosPDF.reset();
1176 }
1177 }
1178 String basePath = getBasePath(request);
1179 String docId = ((PurchaseOrderForm) form).getDocId();
1180 String methodToCallPrintPurchaseOrderPDF = "printPurchaseOrderPDFOnly";
1181 String methodToCallDocHandler = "docHandler";
1182 String printPOPDFUrl = getUrlForPrintPO(basePath, docId, methodToCallPrintPurchaseOrderPDF);
1183 String displayPOTabbedPageUrl = getUrlForPrintPO(basePath, docId, methodToCallDocHandler);
1184 request.setAttribute("printPOPDFUrl", printPOPDFUrl);
1185 request.setAttribute("displayPOTabbedPageUrl", displayPOTabbedPageUrl);
1186 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER);
1187 request.setAttribute("purchaseOrderLabel", label);
1188 GlobalVariables.getUserSession().addObject("isPreview", new Boolean(true));
1189
1190 return mapping.findForward("printPurchaseOrderPDF");
1191 }
1192
1193 /**
1194 * Forwards to the RetransmitForward.jsp page so that we could open 2 windows for retransmit,
1195 * one is to display the PO tabbed page and the other one display the pdf document.
1196 *
1197 * @param mapping
1198 * @param form
1199 * @param request
1200 * @param response
1201 * @return
1202 * @throws Exception
1203 */
1204 public ActionForward printingRetransmitPo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1205 String basePath = getBasePath(request);
1206 String docId = ((PurchaseOrderForm) form).getPurchaseOrderDocument().getDocumentNumber();
1207 String methodToCallPrintRetransmitPurchaseOrderPDF = "printingRetransmitPoOnly";
1208 String methodToCallDocHandler = "docHandler";
1209 String printPOPDFUrl = getUrlForPrintPO(basePath, docId, methodToCallPrintRetransmitPurchaseOrderPDF);
1210 String displayPOTabbedPageUrl = getUrlForPrintPO(basePath, docId, methodToCallDocHandler);
1211
1212 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1213 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1214
1215 StringBuffer itemIndexesBuffer = createSelectedItemIndexes(po.getItems());
1216 if (itemIndexesBuffer.length() > 0) {
1217 itemIndexesBuffer.deleteCharAt(itemIndexesBuffer.lastIndexOf(","));
1218 request.setAttribute("selectedItemIndexes", itemIndexesBuffer.toString());
1219 }
1220
1221 request.setAttribute("printPOPDFUrl", printPOPDFUrl);
1222 request.setAttribute("displayPOTabbedPageUrl", displayPOTabbedPageUrl);
1223 request.setAttribute("docId", docId);
1224 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER);
1225 request.setAttribute("purchaseOrderLabel", label);
1226 return mapping.findForward("retransmitPurchaseOrderPDF");
1227 }
1228
1229 /**
1230 * Helper method to create a StringBuffer of the indexes of items that the user
1231 * has selected for retransmit to be passed in as an attribute to the RetransmitForward
1232 * page so that we could add these items later on to the pdf page.
1233 *
1234 * @param items The List of items on the PurchaseOrderDocument.
1235 * @return
1236 */
1237 protected StringBuffer createSelectedItemIndexes(List<PurchaseOrderItem>items) {
1238 StringBuffer itemIndexesBuffer = new StringBuffer();
1239 int i = 0;
1240 for (PurchaseOrderItem item : items) {
1241 if (item.isItemSelectedForRetransmitIndicator()) {
1242 itemIndexesBuffer.append(i);
1243 itemIndexesBuffer.append(',');
1244 }
1245 i++;
1246 }
1247 return itemIndexesBuffer;
1248 }
1249
1250 /**
1251 * Creates a PDF document based on the PO information and the items that were selected by the user on the Purchase Order
1252 * Retransmit Document page to be retransmitted, then display the PDF to the browser.
1253 *
1254 * @param mapping An ActionMapping
1255 * @param form An ActionForm
1256 * @param request The HttpServletRequest
1257 * @param response The HttpServletResponse
1258 * @throws Exception
1259 * @return An ActionForward
1260 */
1261 public ActionForward printingRetransmitPoOnly(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1262
1263 String selectedItemIndexes = (String)request.getParameter("selectedItemIndexes");
1264 String documentNumber = (String)request.getParameter("poDocumentNumberForRetransmit");
1265 PurchaseOrderDocument po = SpringContext.getBean(PurchaseOrderService.class).getPurchaseOrderByDocumentNumber(documentNumber);
1266 String retransmitHeader = (String)request.getParameter("retransmitHeader");
1267
1268 // setting the isItemSelectedForRetransmitIndicator items of the PO obtained from the database based on its value from
1269 // the po from the form
1270
1271 setItemSelectedForRetransmitIndicatorFromPOInForm(selectedItemIndexes, po.getItems());
1272 po.setRetransmitHeader(retransmitHeader);
1273 ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
1274 try {
1275 StringBuffer sbFilename = new StringBuffer();
1276 sbFilename.append("PURAP_PO_");
1277 sbFilename.append(po.getPurapDocumentIdentifier());
1278 sbFilename.append("_");
1279 sbFilename.append(System.currentTimeMillis());
1280 sbFilename.append(".pdf");
1281
1282 // below method will throw ValidationException if errors are found
1283 SpringContext.getBean(PurchaseOrderService.class).retransmitPurchaseOrderPDF(po, baosPDF);
1284
1285 response.setHeader("Cache-Control", "max-age=30");
1286 response.setContentType("application/pdf");
1287 StringBuffer sbContentDispValue = new StringBuffer();
1288 sbContentDispValue.append("inline");
1289 sbContentDispValue.append("; filename=");
1290 sbContentDispValue.append(sbFilename);
1291
1292 response.setHeader("Content-disposition", sbContentDispValue.toString());
1293
1294 response.setContentLength(baosPDF.size());
1295
1296 ServletOutputStream sos;
1297
1298 sos = response.getOutputStream();
1299
1300 baosPDF.writeTo(sos);
1301
1302 sos.flush();
1303
1304 }
1305 catch (ValidationException e) {
1306 LOG.warn("Caught ValidationException while trying to retransmit PO with doc id " + po.getDocumentNumber());
1307 return mapping.findForward(KFSConstants.MAPPING_ERROR);
1308 }
1309 finally {
1310 if (baosPDF != null) {
1311 baosPDF.reset();
1312 }
1313 }
1314
1315 return null;
1316 }
1317
1318 /**
1319 * Sets the itemSelectedForRetransmitIndicator to true to the items that the
1320 * user has selected for retransmit.
1321 *
1322 * @param selectedItemIndexes The String containing the indexes of items selected to be retransmitted, separated by comma.
1323 * @param itemsFromDB The List of items of the PurchaseOrderDocument obtained from the database.
1324 */
1325 protected void setItemSelectedForRetransmitIndicatorFromPOInForm(String selectedItemIndexes, List itemsFromDB) {
1326 int i = 0;
1327 StringTokenizer tok = new StringTokenizer(selectedItemIndexes, ",");
1328 while (tok.hasMoreTokens()) {
1329 i = Integer.parseInt(tok.nextToken());
1330 ((PurchaseOrderItem) (itemsFromDB.get(i))).setItemSelectedForRetransmitIndicator(true);
1331 }
1332 }
1333
1334 /**
1335 * Checks on a few conditions that would cause a warning message to be displayed on top of the Purchase Order page.
1336 *
1337 * @param po the PurchaseOrderDocument whose status and indicators are to be checked in the conditions
1338 * @return boolean true if the Purchase Order doesn't have any warnings and false otherwise.
1339 */
1340 protected void checkForPOWarnings(PurchaseOrderDocument po, ActionMessages messages) {
1341 // "This is not the current version of this Purchase Order." (curr_ind = N and doc status is not enroute)
1342 if (!po.isPurchaseOrderCurrentIndicator() && !po.getDocumentHeader().getWorkflowDocument().stateIsEnroute()) {
1343 GlobalVariables.getMessageList().add(PurapKeyConstants.WARNING_PURCHASE_ORDER_NOT_CURRENT);
1344 }
1345 // "This document is a pending action. This is not the current version of this Purchase Order" (curr_ind = N and doc status
1346 // is enroute)
1347 if (!po.isPurchaseOrderCurrentIndicator() && po.getDocumentHeader().getWorkflowDocument().stateIsEnroute()) {
1348 GlobalVariables.getMessageList().add(PurapKeyConstants.WARNING_PURCHASE_ORDER_PENDING_ACTION_NOT_CURRENT);
1349 }
1350 // "There is a pending action on this Purchase Order." (pend_action = Y)
1351 if (po.isPendingActionIndicator()) {
1352 GlobalVariables.getMessageList().add(PurapKeyConstants.WARNING_PURCHASE_ORDER_PENDING_ACTION);
1353 }
1354
1355 if (!po.isPurchaseOrderCurrentIndicator()) {
1356 ActionMessage noteMessage = new ActionMessage(PurapKeyConstants.WARNING_PURCHASE_ORDER_ALL_NOTES);
1357 messages.add(PurapConstants.NOTE_TAB_WARNING, noteMessage);
1358 }
1359 }
1360
1361 /**
1362 * Add a stipulation to the document.
1363 *
1364 * @param mapping An ActionMapping
1365 * @param form An ActionForm
1366 * @param request The HttpServletRequest
1367 * @param response The HttpServletResponse
1368 * @throws Exception
1369 * @return An ActionForward
1370 */
1371 public ActionForward addStipulation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1372 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1373 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1374
1375 if (StringUtils.isBlank(poForm.getNewPurchaseOrderVendorStipulationLine().getVendorStipulationDescription())) {
1376 GlobalVariables.getMessageMap().putError(KFSConstants.DOCUMENT_PROPERTY_NAME + "." + PurapPropertyConstants.VENDOR_STIPULATION, PurapKeyConstants.ERROR_STIPULATION_DESCRIPTION);
1377 }
1378 else {
1379 PurchaseOrderVendorStipulation newStipulation = poForm.getAndResetNewPurchaseOrderVendorStipulationLine();
1380 document.getPurchaseOrderVendorStipulations().add(newStipulation);
1381 }
1382
1383 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1384 }
1385
1386 /**
1387 * Delete a stipulation from the document.
1388 *
1389 * @param mapping An ActionMapping
1390 * @param form An ActionForm
1391 * @param request The HttpServletRequest
1392 * @param response The HttpServletResponse
1393 * @throws Exception
1394 * @return An ActionForward
1395 */
1396 public ActionForward deleteStipulation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1397 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1398 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1399 document.getPurchaseOrderVendorStipulations().remove(getSelectedLine(request));
1400
1401 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1402 }
1403
1404 /**
1405 * Overrides the docHandler method in the superclass. In addition to doing the normal process in the superclass and returning
1406 * its action forward from the superclass, it also invokes the <code>checkForPOWarnings</code> method to check on a few
1407 * conditions that could have caused warning messages to be displayed on top of Purchase Order page.
1408 *
1409 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#docHandler(org.apache.struts.action.ActionMapping,
1410 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
1411 */
1412 @Override
1413 public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1414 ActionForward forward = super.docHandler(mapping, form, request, response);
1415 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1416 PurchaseOrderDocument po = (PurchaseOrderDocument) poForm.getDocument();
1417
1418 ActionMessages messages = new ActionMessages();
1419 checkForPOWarnings(po, messages);
1420 saveMessages(request, messages);
1421 return forward;
1422 }
1423
1424 /**
1425 * Sets up the PO document for Quote processing.
1426 *
1427 * @param mapping An ActionMapping
1428 * @param form An ActionForm
1429 * @param request The HttpServletRequest
1430 * @param response The HttpServletResponse
1431 * @throws Exception
1432 * @return An ActionForward
1433 */
1434 public ActionForward initiateQuote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1435 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
1436 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1437 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1438 if (!PurchaseOrderStatuses.IN_PROCESS.equals(document.getStatusCode())) {
1439 // PO must be "in process" in order to initiate a quote
1440 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_NOT_IN_PROCESS);
1441 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1442 }
1443 Calendar currentCalendar = dateTimeService.getCurrentCalendar();
1444 Date currentSqlDate = new java.sql.Date(currentCalendar.getTimeInMillis());
1445 document.setPurchaseOrderQuoteInitializationDate(currentSqlDate);
1446 document.setStatusCode(PurchaseOrderStatuses.QUOTE);
1447 document.setStatusChange(PurchaseOrderStatuses.QUOTE);
1448 document.refreshReferenceObject(PurapPropertyConstants.STATUS);
1449
1450 //TODO this needs to be done better, and probably make it a parameter
1451 Calendar expCalendar = (Calendar) currentCalendar.clone();
1452 expCalendar.add(Calendar.DAY_OF_MONTH, 10);
1453 java.sql.Date expDate = new java.sql.Date(expCalendar.getTimeInMillis());
1454
1455 document.setPurchaseOrderQuoteDueDate(expDate);
1456 document.getPurchaseOrderVendorQuotes().clear();
1457 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(document);
1458
1459 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1460 }
1461
1462 /**
1463 * Add to the Quotes a line to contain a Vendor.
1464 *
1465 * @param mapping An ActionMapping
1466 * @param form An ActionForm
1467 * @param request The HttpServletRequest
1468 * @param response The HttpServletResponse
1469 * @throws Exception
1470 * @return An ActionForward
1471 */
1472 public ActionForward addVendor(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1473 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1474 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1475 PurchaseOrderVendorQuote vendorQuote = poForm.getNewPurchaseOrderVendorQuote();
1476 String errorPrefix = PurapPropertyConstants.NEW_PURCHASE_ORDER_VENDOR_QUOTE_TEXT;
1477 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedAddVendorToQuoteEvent(errorPrefix, document, vendorQuote));
1478 if (rulePassed) {
1479 poForm.getNewPurchaseOrderVendorQuote().setDocumentNumber(document.getDocumentNumber());
1480 document.getPurchaseOrderVendorQuotes().add(vendorQuote);
1481 poForm.setNewPurchaseOrderVendorQuote(new PurchaseOrderVendorQuote());
1482 }
1483 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1484 }
1485
1486 /**
1487 * Deletes a Vendor from the list of those from which a Quote should be obtained.
1488 *
1489 * @param mapping An ActionMapping
1490 * @param form An ActionForm
1491 * @param request The HttpServletRequest
1492 * @param response The HttpServletResponse
1493 * @throws Exception
1494 * @return An ActionForward
1495 */
1496 public ActionForward deleteVendor(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1497 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1498 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1499 document.getPurchaseOrderVendorQuotes().remove(getSelectedLine(request));
1500
1501 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1502 }
1503
1504 /**
1505 * Once an awarded Vendor number is present on the PO, verifies the fact, asks the user for confirmation to complete the quoting
1506 * process with the awarded Vendor, and sets the Vendor information on the purchase order, if confirmation is obtained.
1507 *
1508 * @param mapping An ActionMapping
1509 * @param form An ActionForm
1510 * @param request The HttpServletRequest
1511 * @param response The HttpServletResponse
1512 * @throws Exception
1513 * @return An ActionForward
1514 */
1515 public ActionForward completeQuote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1516 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1517 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1518 PurchaseOrderVendorQuote awardedQuote = new PurchaseOrderVendorQuote();
1519
1520 // verify that all vendors have a quote status
1521 // also run dictionary validations to validate against the DD.
1522 boolean dictionaryValid = true;
1523 for (PurchaseOrderVendorQuote poQuote : document.getPurchaseOrderVendorQuotes()) {
1524 if (poQuote.getPurchaseOrderQuoteStatusCode() == null) {
1525 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_STATUS_NOT_SELECTED);
1526 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1527 }
1528 else {
1529 dictionaryValid &= SpringContext.getBean(DictionaryValidationService.class).isBusinessObjectValid(poQuote, PurapPropertyConstants.VENDOR_QUOTES);
1530 }
1531 }
1532
1533 if (!dictionaryValid) {
1534 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1535 }
1536
1537 // verify quote status fields
1538 if (poForm.getAwardedVendorNumber() == null) {
1539 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_NO_VENDOR_AWARDED);
1540
1541 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1542 }
1543 else {
1544 awardedQuote = document.getPurchaseOrderVendorQuote(poForm.getAwardedVendorNumber().intValue());
1545 if (awardedQuote.getPurchaseOrderQuoteStatusCode() == null) {
1546 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_NOT_TRANSMITTED);
1547
1548 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1549 }
1550 else {
1551 VendorDetail awardedVendor = SpringContext.getBean(VendorService.class).getVendorDetail(awardedQuote.getVendorHeaderGeneratedIdentifier(), awardedQuote.getVendorDetailAssignedIdentifier());
1552 if (!awardedVendor.getVendorHeader().getVendorTypeCode().equals("PO")) {
1553 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_AWARD_NON_PO);
1554
1555 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1556 }
1557 }
1558 }
1559
1560 // use question framework to make sure they REALLY want to complete the quote...
1561 // since the html table tags are not supported for now, the awarded vendor info is displayed without them.
1562 // String message = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_CONFIRM_AWARD);
1563 // String vendorRow = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_CONFIRM_AWARD_ROW);
1564 //
1565 // String tempRows = "";
1566 // for (PurchaseOrderVendorQuote poQuote : document.getPurchaseOrderVendorQuotes()) {
1567 // String tempRow = vendorRow;
1568 // tempRow = StringUtils.replace(tempRow, "{0}", poQuote.getVendorName());
1569 // if (poQuote.getPurchaseOrderQuoteAwardTimestamp() == null) {
1570 // if (awardedQuote.getVendorNumber().equals(poQuote.getVendorNumber())) {
1571 // tempRow = StringUtils.replace(tempRow, "{1}", SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().toString());
1572 // }
1573 // else {
1574 // tempRow = StringUtils.replace(tempRow, "{1}", "");
1575 // }
1576 // }
1577 // else {
1578 // tempRow = StringUtils.replace(tempRow, "{1}", poQuote.getPurchaseOrderQuoteAwardTimestamp().toString());
1579 // }
1580 // if (poQuote.getPurchaseOrderQuoteStatusCode() != null) {
1581 // poQuote.refreshReferenceObject(PurapPropertyConstants.PURCHASE_ORDER_QUOTE_STATUS);
1582 // tempRow = StringUtils.replace(tempRow, "{2}", poQuote.getPurchaseOrderQuoteStatus().getStatusDescription());
1583 // }
1584 // else {
1585 // tempRow = StringUtils.replace(tempRow, "{2}", "N/A");
1586 // }
1587 // if (poQuote.getPurchaseOrderQuoteRankNumber() != null) {
1588 // tempRow = StringUtils.replace(tempRow, "{3}", poQuote.getPurchaseOrderQuoteRankNumber());
1589 // }
1590 // else {
1591 // tempRow = StringUtils.replace(tempRow, "{3}", "N/A");
1592 // }
1593 // tempRows += tempRow;
1594 // }
1595 // message = StringUtils.replace(message, "{0}", tempRows);
1596 // without the html table tags
1597 StringBuffer awardedVendorInfo = new StringBuffer(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_CONFIRM_AWARD));
1598 int awardNbr = 0;
1599 for (PurchaseOrderVendorQuote poQuote : document.getPurchaseOrderVendorQuotes()) {
1600
1601 // vendor name
1602 awardedVendorInfo.append(++awardNbr + ". ").append("Vendor Name: ");
1603 awardedVendorInfo.append(poQuote.getVendorName()).append("[br]");
1604
1605 // awarded date
1606 awardedVendorInfo.append("Awarded Date: ");
1607 if (poQuote.getPurchaseOrderQuoteAwardTimestamp() == null) {
1608 if (awardedQuote.getVendorNumber().equals(poQuote.getVendorNumber())) {
1609 awardedVendorInfo.append(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate().toString());
1610 }
1611 }
1612 else {
1613 awardedVendorInfo.append(poQuote.getPurchaseOrderQuoteAwardTimestamp().toString());
1614 }
1615 awardedVendorInfo.append("[br]");
1616
1617 // quote status
1618 awardedVendorInfo.append("Quote Status: ");
1619 if (poQuote.getPurchaseOrderQuoteStatusCode() != null) {
1620 poQuote.refreshReferenceObject(PurapPropertyConstants.PURCHASE_ORDER_QUOTE_STATUS);
1621 awardedVendorInfo.append(poQuote.getPurchaseOrderQuoteStatus().getStatusDescription());
1622 }
1623 else {
1624 awardedVendorInfo.append("N/A");
1625 }
1626 awardedVendorInfo.append("[br]");
1627
1628 // rank
1629 awardedVendorInfo.append("Rank: ");
1630 if (poQuote.getPurchaseOrderQuoteRankNumber() != null) {
1631 awardedVendorInfo.append(poQuote.getPurchaseOrderQuoteRankNumber());
1632 }
1633 else {
1634 awardedVendorInfo.append("N/A");
1635 }
1636 awardedVendorInfo.append("[br][br]");
1637 }
1638
1639 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
1640 if (question == null) {
1641 // ask question if not already asked
1642 return performQuestionWithoutInput(mapping, form, request, response, PODocumentsStrings.CONFIRM_AWARD_QUESTION, awardedVendorInfo.toString(), KFSConstants.CONFIRMATION_QUESTION, PODocumentsStrings.CONFIRM_AWARD_RETURN, "");
1643 }
1644 else {
1645 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
1646 if ((PODocumentsStrings.CONFIRM_AWARD_QUESTION.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
1647 // set awarded date
1648 awardedQuote.setPurchaseOrderQuoteAwardTimestamp(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp());
1649
1650 Date currentSqlDate = SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
1651 document.setPurchaseOrderQuoteAwardedDate(currentSqlDate);
1652
1653 // PO vendor information updated with awarded vendor
1654 document.setVendorName(awardedQuote.getVendorName());
1655 document.setVendorNumber(awardedQuote.getVendorNumber());
1656 Integer headID = awardedQuote.getVendorHeaderGeneratedIdentifier();
1657 Integer detailID = awardedQuote.getVendorDetailAssignedIdentifier();
1658 document.setVendorHeaderGeneratedIdentifier(headID);
1659 document.setVendorDetailAssignedIdentifier(detailID);
1660
1661 // use PO type address to fill in vendor address
1662 String campusCode = GlobalVariables.getUserSession().getPerson().getCampusCode();
1663 VendorAddress pova = SpringContext.getBean(VendorService.class).getVendorDefaultAddress(headID, detailID, AddressTypes.PURCHASE_ORDER, campusCode);
1664 document.setVendorLine1Address(pova.getVendorLine1Address());
1665 document.setVendorLine2Address(pova.getVendorLine2Address());
1666 document.setVendorCityName(pova.getVendorCityName());
1667 document.setVendorStateCode(pova.getVendorStateCode());
1668 document.setVendorPostalCode(pova.getVendorZipCode());
1669 document.setVendorCountryCode(pova.getVendorCountryCode());
1670 document.setVendorFaxNumber(pova.getVendorFaxNumber());
1671
1672 document.setStatusCode(PurapConstants.PurchaseOrderStatuses.IN_PROCESS);
1673 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(document);
1674 }
1675 }
1676
1677 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1678 }
1679
1680 /**
1681 * Cancels the process of obtaining quotes. Checks whether any of the quote requests have been transmitted. If none have, tries
1682 * to obtain confirmation from the user for the cancellation. If confirmation is obtained, clears out the list of Vendors from
1683 * which to obtain quotes and writes the given reason to a note on the PO.
1684 *
1685 * @param mapping An ActionMapping
1686 * @param form An ActionForm
1687 * @param request The HttpServletRequest
1688 * @param response The HttpServletResponse
1689 * @throws Exception
1690 * @return An ActionForward
1691 */
1692 public ActionForward cancelQuote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1693 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1694 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1695
1696 for (PurchaseOrderVendorQuote quotedVendors : document.getPurchaseOrderVendorQuotes()) {
1697 if (quotedVendors.getPurchaseOrderQuoteTransmitTimestamp() != null) {
1698 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.VENDOR_QUOTES, PurapKeyConstants.ERROR_PURCHASE_ORDER_QUOTE_ALREADY_TRASNMITTED);
1699
1700 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1701 }
1702 }
1703
1704 String message = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_CONFIRM_CANCEL_QUOTE);
1705 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
1706
1707 if (question == null) {
1708
1709 // ask question if not already asked
1710 return performQuestionWithInput(mapping, form, request, response, PODocumentsStrings.CONFIRM_CANCEL_QUESTION, message, KFSConstants.CONFIRMATION_QUESTION, PODocumentsStrings.CONFIRM_CANCEL_RETURN, "");
1711 }
1712 else {
1713 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
1714 if ((PODocumentsStrings.CONFIRM_CANCEL_QUESTION.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
1715 String reason = request.getParameter(KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME);
1716
1717 if (StringUtils.isEmpty(reason)) {
1718
1719 return performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, PODocumentsStrings.CONFIRM_CANCEL_QUESTION, message, KFSConstants.CONFIRMATION_QUESTION, PODocumentsStrings.CONFIRM_CANCEL_RETURN, "", "", PurapKeyConstants.ERROR_PURCHASE_ORDER_REASON_REQUIRED, KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME, "250");
1720 }
1721 document.getPurchaseOrderVendorQuotes().clear();
1722 Note cancelNote = new Note();
1723 cancelNote.setAuthorUniversalIdentifier(GlobalVariables.getUserSession().getPerson().getPrincipalId());
1724 String reasonPrefix = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_CANCEL_QUOTE_NOTE_TEXT);
1725 cancelNote.setNoteText(reasonPrefix + reason);
1726 document.addNote(cancelNote);
1727 document.setStatusCode(PurapConstants.PurchaseOrderStatuses.IN_PROCESS);
1728 //being required to add notes about changing po status even though i'm not changing status
1729 document.setStatusChange(null);
1730 SpringContext.getBean(PurapService.class).saveDocumentNoValidation(document);
1731 }
1732 }
1733
1734 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1735 }
1736
1737 /**
1738 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#cancel(org.apache.struts.action.ActionMapping,
1739 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
1740 */
1741 @Override
1742 public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1743 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
1744 // this should probably be moved into a protected instance variable
1745 KualiConfigurationService kualiConfiguration = SpringContext.getBean(KualiConfigurationService.class);
1746
1747 // logic for cancel question
1748 if (question == null) {
1749
1750 // ask question if not already asked
1751 return this.performQuestionWithoutInput(mapping, form, request, response, KFSConstants.DOCUMENT_CANCEL_QUESTION, kualiConfiguration.getPropertyString("document.question.cancel.text"), KFSConstants.CONFIRMATION_QUESTION, KFSConstants.MAPPING_CANCEL, "");
1752 }
1753 else {
1754 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
1755 if ((KFSConstants.DOCUMENT_CANCEL_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) {
1756
1757 // if no button clicked just reload the doc
1758 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1759 }
1760 // else go to cancel logic below
1761 }
1762
1763 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1764 SpringContext.getBean(DocumentService.class).cancelDocument(kualiDocumentFormBase.getDocument(), kualiDocumentFormBase.getAnnotation());
1765
1766 return returnToSender(request, mapping, kualiDocumentFormBase);
1767 }
1768
1769 /**
1770 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#save(org.apache.struts.action.ActionMapping,
1771 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
1772 */
1773 @Override
1774 public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1775 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1776 PurchaseOrderDocument po = poForm.getPurchaseOrderDocument();
1777
1778 if (StringUtils.isNotBlank(po.getStatusCode()) && StringUtils.isNotBlank(po.getStatusChange()) && (!StringUtils.equals(po.getStatusCode(), po.getStatusChange()))) {
1779
1780 KualiWorkflowDocument workflowDocument = po.getDocumentHeader().getWorkflowDocument();
1781 if (ObjectUtils.isNull(workflowDocument) || workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) {
1782
1783 return this.askSaveQuestions(mapping, form, request, response, PODocumentsStrings.MANUAL_STATUS_CHANGE_QUESTION);
1784 }
1785 }
1786
1787 return super.save(mapping, form, request, response);
1788 }
1789
1790 /**
1791 * Obtains confirmation and records reasons for the manual status changes which can take place before the purchase order has
1792 * been routed. If confirmation is given, changes the status, saves, and records the given reason in an note on the purchase
1793 * order.
1794 *
1795 * @param mapping An ActionMapping
1796 * @param form An ActionForm
1797 * @param request The HttpServletRequest
1798 * @param response The HttpServletResponse
1799 * @return An ActionForward
1800 */
1801 protected ActionForward askSaveQuestions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String questionType) {
1802 KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1803 PurchaseOrderDocument po = (PurchaseOrderDocument) kualiDocumentFormBase.getDocument();
1804 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
1805 String reason = request.getParameter(KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME);
1806 KualiConfigurationService kualiConfiguration = SpringContext.getBean(KualiConfigurationService.class);
1807 ActionForward forward = mapping.findForward(KFSConstants.MAPPING_BASIC);
1808 String notePrefix = "";
1809
1810 if (StringUtils.equals(questionType, PODocumentsStrings.MANUAL_STATUS_CHANGE_QUESTION) && ObjectUtils.isNull(question)) {
1811 String message = kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_MANUAL_STATUS_CHANGE);
1812 try {
1813
1814 return this.performQuestionWithInput(mapping, form, request, response, questionType, message, KFSConstants.CONFIRMATION_QUESTION, questionType, "");
1815 }
1816 catch (Exception e) {
1817 throw new RuntimeException(e);
1818 }
1819 }
1820 else {
1821 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
1822 if (question.equals(questionType) && buttonClicked.equals(ConfirmationQuestion.NO)) {
1823 // If 'No' is the button clicked, just reload the doc
1824 return forward;
1825 }
1826
1827 // Build out full message.
1828 if (StringUtils.equals(questionType, PODocumentsStrings.MANUAL_STATUS_CHANGE_QUESTION)) {
1829 Map<String, String> manuallyChangeableStatuses = new HashMap<String, String>();
1830 manuallyChangeableStatuses.put(PurchaseOrderStatuses.IN_PROCESS, "In Process");
1831 manuallyChangeableStatuses.put(PurchaseOrderStatuses.WAITING_FOR_VENDOR, "Waiting for Vendor");
1832 manuallyChangeableStatuses.put(PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT, "Waiting for Department");
1833
1834 String key = kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_MANUAL_STATUS_CHANGE_NOTE_PREFIX);
1835 String oldStatus = manuallyChangeableStatuses.get(po.getStatusCode());
1836 String newStatus = manuallyChangeableStatuses.get(po.getStatusChange());
1837 key = StringUtils.replace(key, "{0}", (StringUtils.isBlank(oldStatus) ? " " : oldStatus));
1838 notePrefix = StringUtils.replace(key, "{1}", (StringUtils.isBlank(newStatus) ? " " : newStatus));
1839 }
1840 String noteText = notePrefix + KFSConstants.BLANK_SPACE + reason;
1841 int noteTextLength = noteText.length();
1842
1843 // Get note text max length from DD.
1844 int noteTextMaxLength = SpringContext.getBean(DataDictionaryService.class).getAttributeMaxLength(Note.class, KFSConstants.NOTE_TEXT_PROPERTY_NAME).intValue();
1845
1846 if (StringUtils.isBlank(reason) || (noteTextLength > noteTextMaxLength)) {
1847 // Figure out exact number of characters that the user can enter.
1848 int reasonLimit = noteTextMaxLength - noteTextLength;
1849
1850 if (ObjectUtils.isNull(reason)) {
1851 // Prevent a NPE by setting the reason to a blank string.
1852 reason = "";
1853 }
1854
1855 try {
1856 if (StringUtils.equals(questionType, PODocumentsStrings.MANUAL_STATUS_CHANGE_QUESTION)) {
1857
1858 return this.performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response, questionType, kualiConfiguration.getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_MANUAL_STATUS_CHANGE), KFSConstants.CONFIRMATION_QUESTION, questionType, "", reason, PurapKeyConstants.ERROR_PURCHASE_ORDER_REASON_REQUIRED, KFSConstants.QUESTION_REASON_ATTRIBUTE_NAME, new Integer(reasonLimit).toString());
1859 }
1860 }
1861 catch (Exception e) {
1862 throw new RuntimeException(e);
1863 }
1864 }
1865 else if (StringUtils.equals(questionType, PODocumentsStrings.MANUAL_STATUS_CHANGE_QUESTION)) {
1866 executeManualStatusChange(po);
1867 try {
1868 forward = super.save(mapping, form, request, response);
1869 }
1870 catch (Exception e) {
1871 throw new RuntimeException(e);
1872 }
1873 }
1874 Note newNote = new Note();
1875 newNote.setNoteText(noteText);
1876 newNote.setNoteTypeCode(KFSConstants.NoteTypeEnum.BUSINESS_OBJECT_NOTE_TYPE.getCode());
1877 kualiDocumentFormBase.setNewNote(newNote);
1878 try {
1879 insertBONote(mapping, kualiDocumentFormBase, request, response);
1880 }
1881 catch (Exception e) {
1882 throw new RuntimeException(e);
1883 }
1884 }
1885
1886 return forward;
1887 }
1888
1889 /**
1890 * Applies a manual change of status to the given purchase order document.
1891 *
1892 * @param po A PurchaseOrderDocument
1893 */
1894 protected void executeManualStatusChange(PurchaseOrderDocument po) {
1895 try {
1896 SpringContext.getBean(PurapService.class).updateStatus(po, po.getStatusChange());
1897 }
1898 catch (Exception e) {
1899 throw new RuntimeException(e);
1900 }
1901 }
1902
1903 /**
1904 * @see org.kuali.kfs.module.purap.document.web.struts.PurchasingAccountsPayableActionBase#loadDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
1905 */
1906 @Override
1907 protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
1908 super.loadDocument(kualiDocumentFormBase);
1909 PurchaseOrderForm poForm = (PurchaseOrderForm) kualiDocumentFormBase;
1910 PurchaseOrderDocument po = (PurchaseOrderDocument) poForm.getDocument();
1911 po.setInternalPurchasingLimit(SpringContext.getBean(PurchaseOrderService.class).getInternalPurchasingDollarLimit(po));
1912 }
1913
1914 /**
1915 * Adds a PurchasingItemCapitalAsset (a container for the Capital Asset Number) to the selected
1916 * item's list.
1917 *
1918 * @param mapping An ActionMapping
1919 * @param form The Form
1920 * @param request An HttpServletRequest
1921 * @param response The HttpServletResponse
1922 * @return An ActionForward
1923 * @throws Exception
1924 */
1925 public ActionForward addAsset(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1926 PurchaseOrderForm poForm = (PurchaseOrderForm)form;
1927 PurchaseOrderDocument document = (PurchaseOrderDocument)poForm.getDocument();
1928 PurchaseOrderItem item = (PurchaseOrderItem)document.getItemByLineNumber(getSelectedLine(request) + 1);
1929 //TODO: Add a new way to add assets to the system.
1930 //item.addAsset();
1931 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1932 }
1933
1934 public ActionForward removeAlternateVendor(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1935 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1936 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1937
1938 document.setAlternateVendorDetailAssignedIdentifier(null);
1939 document.setAlternateVendorHeaderGeneratedIdentifier(null);
1940 document.setAlternateVendorName(null);
1941 document.setAlternateVendorNumber(null);
1942
1943 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1944 }
1945
1946 public ActionForward createReceivingLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1947 PurchaseOrderForm poForm = (PurchaseOrderForm) form;
1948 PurchaseOrderDocument document = (PurchaseOrderDocument) poForm.getDocument();
1949
1950 String basePath = getBasePath(request);
1951 String methodToCallDocHandler = "docHandler";
1952 String methodToCallReceivingLine = "initiate";
1953
1954 //set parameters
1955 Properties parameters = new Properties();
1956 parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCallDocHandler);
1957 parameters.put(KFSConstants.PARAMETER_COMMAND, methodToCallReceivingLine);
1958 parameters.put(KFSConstants.DOCUMENT_TYPE_NAME, "RCVL");
1959 parameters.put("purchaseOrderId", document.getPurapDocumentIdentifier().toString() );
1960
1961 //create url
1962 String receivingUrl = UrlFactory.parameterizeUrl(basePath + "/" + "purapLineItemReceiving.do", parameters);
1963
1964 //create forward
1965 ActionForward forward = new ActionForward(receivingUrl, true);
1966
1967 return forward;
1968 }
1969
1970 public ActionForward resendPoCxml(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1971 PurchaseOrderDocument po = (PurchaseOrderDocument) ((PurchaseOrderForm) form).getDocument();
1972 SpringContext.getBean(PurchaseOrderService.class).retransmitB2BPurchaseOrder(po);
1973 return mapping.findForward(KFSConstants.MAPPING_BASIC);
1974 }
1975
1976 }
1977