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.util.HashMap; 019 import java.util.List; 020 import java.util.Properties; 021 022 import javax.servlet.http.HttpServletRequest; 023 import javax.servlet.http.HttpServletResponse; 024 025 import org.apache.commons.lang.StringUtils; 026 import org.apache.struts.action.ActionForm; 027 import org.apache.struts.action.ActionForward; 028 import org.apache.struts.action.ActionMapping; 029 import org.kuali.kfs.module.purap.PurapConstants; 030 import org.kuali.kfs.module.purap.PurapKeyConstants; 031 import org.kuali.kfs.module.purap.PurapPropertyConstants; 032 import org.kuali.kfs.module.purap.PurapConstants.CorrectionReceivingDocumentStrings; 033 import org.kuali.kfs.module.purap.PurapConstants.PREQDocumentsStrings; 034 import org.kuali.kfs.module.purap.businessobject.LineItemReceivingItem; 035 import org.kuali.kfs.module.purap.document.LineItemReceivingDocument; 036 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 037 import org.kuali.kfs.module.purap.document.ReceivingDocument; 038 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; 039 import org.kuali.kfs.module.purap.document.service.ReceivingService; 040 import org.kuali.kfs.module.purap.document.validation.event.AddReceivingItemEvent; 041 import org.kuali.kfs.module.purap.util.ReceivingQuestionCallback; 042 import org.kuali.kfs.sys.KFSConstants; 043 import org.kuali.kfs.sys.KFSKeyConstants; 044 import org.kuali.kfs.sys.KFSPropertyConstants; 045 import org.kuali.kfs.sys.context.SpringContext; 046 import org.kuali.rice.kew.exception.WorkflowException; 047 import org.kuali.rice.kim.util.KimConstants; 048 import org.kuali.rice.kns.question.ConfirmationQuestion; 049 import org.kuali.rice.kns.service.DocumentHelperService; 050 import org.kuali.rice.kns.service.KualiRuleService; 051 import org.kuali.rice.kns.util.GlobalVariables; 052 import org.kuali.rice.kns.util.KNSConstants; 053 import org.kuali.rice.kns.util.KualiDecimal; 054 import org.kuali.rice.kns.util.ObjectUtils; 055 import org.kuali.rice.kns.util.UrlFactory; 056 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 057 058 public class LineItemReceivingAction extends ReceivingBaseAction { 059 060 protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { 061 062 super.createDocument(kualiDocumentFormBase); 063 064 LineItemReceivingForm rlf = (LineItemReceivingForm)kualiDocumentFormBase; 065 LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument(); 066 067 //set identifier from form value 068 rlDoc.setPurchaseOrderIdentifier( rlf.getPurchaseOrderId() ); 069 070 rlDoc.initiateDocument(); 071 072 } 073 074 public ActionForward continueReceivingLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 075 LineItemReceivingForm rlf = (LineItemReceivingForm)form; 076 LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument(); 077 078 GlobalVariables.getMessageMap().clearErrorPath(); 079 GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.DOCUMENT); 080 boolean valid = true; 081 boolean poNotNull = true; 082 083 //check for a po id 084 if (ObjectUtils.isNull(rlDoc.getPurchaseOrderIdentifier())) { 085 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, KFSKeyConstants.ERROR_REQUIRED, PREQDocumentsStrings.PURCHASE_ORDER_ID); 086 poNotNull = false; 087 } 088 089 if (ObjectUtils.isNull(rlDoc.getShipmentReceivedDate())) { 090 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.SHIPMENT_RECEIVED_DATE, KFSKeyConstants.ERROR_REQUIRED, PurapConstants.LineItemReceivingDocumentStrings.VENDOR_DATE); 091 } 092 093 //exit early as the po is null, no need to proceed further until this is taken care of 094 if(poNotNull == false){ 095 return mapping.findForward(KFSConstants.MAPPING_BASIC); 096 } 097 098 PurchaseOrderDocument po = SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(rlDoc.getPurchaseOrderIdentifier()); 099 if (ObjectUtils.isNotNull(po)) { 100 // TODO figure out a more straightforward way to do this. ailish put this in so the link id would be set and the perm check would work 101 rlDoc.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier()); 102 103 //TODO hjs-check to see if user is allowed to initiate doc based on PO sensitive data (add this to all other docs except acm doc) 104 if (!SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(rlDoc).isAuthorizedByTemplate(rlDoc, KNSConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, GlobalVariables.getUserSession().getPrincipalId())) { 105 throw buildAuthorizationException("initiate document", rlDoc); 106 } 107 }else{ 108 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_PURCHASE_ORDER_NOT_EXIST); 109 return mapping.findForward(KFSConstants.MAPPING_BASIC); 110 } 111 112 //perform duplicate check 113 ActionForward forward = performDuplicateReceivingLineCheck(mapping, form, request, response, rlDoc); 114 if( forward != null ){ 115 return forward; 116 } 117 118 if (!SpringContext.getBean(ReceivingService.class).isPurchaseOrderActiveForLineItemReceivingDocumentCreation(rlDoc.getPurchaseOrderIdentifier())){ 119 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_PO_NOT_ACTIVE, rlDoc.getPurchaseOrderIdentifier().toString()); 120 valid &= false; 121 } 122 123 if( SpringContext.getBean(ReceivingService.class).canCreateLineItemReceivingDocument(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber()) == false){ 124 String inProcessDocNum = ""; 125 List<String> inProcessDocNumbers = SpringContext.getBean(ReceivingService.class).getLineItemReceivingDocumentNumbersInProcessForPurchaseOrder(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber()); 126 if (!inProcessDocNumbers.isEmpty()) { // should not be empty if we reach this point 127 inProcessDocNum = inProcessDocNumbers.get(0); 128 } 129 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_ACTIVE_FOR_PO, inProcessDocNum, rlDoc.getPurchaseOrderIdentifier().toString()); 130 valid &= false; 131 } 132 133 //populate and save Receiving Line Document from Purchase Order, only if we passed all the rules 134 if(valid){ 135 SpringContext.getBean(ReceivingService.class).populateAndSaveLineItemReceivingDocument(rlDoc); 136 } 137 138 return mapping.findForward(KFSConstants.MAPPING_BASIC); 139 } 140 141 public ActionForward createReceivingCorrection(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 142 LineItemReceivingForm rlForm = (LineItemReceivingForm) form; 143 LineItemReceivingDocument document = (LineItemReceivingDocument) rlForm.getDocument(); 144 145 String operation = "AddCorrectionNote "; 146 147 ReceivingQuestionCallback callback = new ReceivingQuestionCallback() { 148 public boolean questionComplete = false; 149 protected String correctionDocumentnoteText; 150 151 public ReceivingDocument doPostQuestion(ReceivingDocument document, String noteText) throws Exception { 152 //mark question completed 153 this.setQuestionComplete(true); 154 this.setCorrectionDocumentCreationNoteText(noteText); 155 return document; 156 } 157 158 public boolean isQuestionComplete(){ 159 return this.questionComplete; 160 } 161 162 public void setQuestionComplete(boolean questionComplete){ 163 this.questionComplete = questionComplete; 164 } 165 166 public String getCorrectionDocumentCreationNoteText() { 167 return correctionDocumentnoteText; 168 } 169 170 public void setCorrectionDocumentCreationNoteText(String noteText) { 171 correctionDocumentnoteText = noteText; 172 } 173 }; 174 175 //ask question 176 ActionForward forward = askQuestionWithInput(mapping, form, request, response, CorrectionReceivingDocumentStrings.NOTE_QUESTION, CorrectionReceivingDocumentStrings.NOTE_PREFIX, operation, PurapKeyConstants.MESSAGE_RECEIVING_CORRECTION_NOTE, callback); 177 178 //if question asked is complete, then route 179 if(callback.isQuestionComplete()){ 180 181 //set parameters 182 String basePath = getBasePath(request); 183 String methodToCallDocHandler = "docHandler"; 184 String methodToCallReceivingCorrection = "initiate"; 185 186 Properties parameters = new Properties(); 187 parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCallDocHandler); 188 parameters.put(KFSConstants.PARAMETER_COMMAND, methodToCallReceivingCorrection); 189 parameters.put(KFSConstants.DOCUMENT_TYPE_NAME, "RCVC"); 190 parameters.put("receivingLineDocId", document.getDocumentHeader().getDocumentNumber() ); 191 parameters.put(PurapConstants.CorrectionReceivingDocumentStrings.CORRECTION_RECEIVING_CREATION_NOTE_PARAMETER, callback.getCorrectionDocumentCreationNoteText()); 192 193 //create url 194 String receivingCorrectionUrl = UrlFactory.parameterizeUrl(basePath + "/" + "purapCorrectionReceiving.do", parameters); 195 //create forward 196 forward = new ActionForward(receivingCorrectionUrl, true); 197 } 198 199 return forward; 200 201 } 202 203 public ActionForward clearInitFields(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 204 LineItemReceivingForm rlForm = (LineItemReceivingForm) form; 205 LineItemReceivingDocument rlDocument = (LineItemReceivingDocument) rlForm.getDocument(); 206 rlDocument.clearInitFields(rlForm.isFromPurchaseOrder()); 207 208 return mapping.findForward(KFSConstants.MAPPING_BASIC); 209 } 210 211 protected ActionForward performDuplicateReceivingLineCheck(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, LineItemReceivingDocument lineItemReceivingDocument) throws Exception { 212 ActionForward forward = null; 213 HashMap<String, String> duplicateMessages = SpringContext.getBean(ReceivingService.class).receivingLineDuplicateMessages(lineItemReceivingDocument); 214 if (duplicateMessages != null && !duplicateMessages.isEmpty()) { 215 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME); 216 if (question == null) { 217 218 return this.performQuestionWithoutInput(mapping, form, request, response, PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION, duplicateMessages.get(PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION), KFSConstants.CONFIRMATION_QUESTION, KFSConstants.ROUTE_METHOD, ""); 219 } 220 221 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); 222 if ((PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { 223 forward = mapping.findForward(KFSConstants.MAPPING_BASIC); 224 } 225 } 226 227 return forward; 228 } 229 /** 230 * Add a new item to the document. 231 * 232 * @param mapping An ActionMapping 233 * @param form An ActionForm 234 * @param request The HttpServletRequest 235 * @param response The HttpServletResponse 236 * @throws Exception 237 * @return An ActionForward 238 */ 239 public ActionForward addItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 240 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 241 LineItemReceivingItem item = lineItemReceivingForm.getNewLineItemReceivingItemLine(); 242 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 243 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AddReceivingItemEvent(PurapPropertyConstants.NEW_LINE_ITEM_RECEIVING_ITEM_LINE, lineItemReceivingDocument, item)); 244 245 if (rulePassed) { 246 item = lineItemReceivingForm.getAndResetNewReceivingItemLine(); 247 lineItemReceivingDocument.addItem(item); 248 //TODO: we need to set the line number correctly to match up to PO 249 } 250 251 return mapping.findForward(KFSConstants.MAPPING_BASIC); 252 } 253 254 /** 255 * For each item, it's quantity received value is set to zero. 256 * 257 * @param mapping 258 * @param form 259 * @param request 260 * @param response 261 * @return 262 * @throws Exception 263 */ 264 public ActionForward clearQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 265 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 266 267 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 268 269 for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){ 270 item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); 271 } 272 273 return mapping.findForward(KFSConstants.MAPPING_BASIC); 274 } 275 276 /** 277 * For each item, loads total order quantity minus prior received quantity into total received quantity. 278 * 279 * @param mapping 280 * @param form 281 * @param request 282 * @param response 283 * @return 284 * @throws Exception 285 */ 286 public ActionForward loadQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 287 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 288 289 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 290 291 for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){ 292 if (item.isOrderedItem()){ 293 if( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()).isGreaterEqual(KualiDecimal.ZERO) ){ 294 item.setItemReceivedTotalQuantity( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()) ); 295 }else{ 296 item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); 297 } 298 } 299 } 300 301 return mapping.findForward(KFSConstants.MAPPING_BASIC); 302 } 303 304 }