001/* 002 * Copyright 2008 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 */ 016package org.kuali.ole.module.purap.document.web.struts; 017 018import org.apache.struts.action.ActionForm; 019import org.apache.struts.action.ActionForward; 020import org.apache.struts.action.ActionMapping; 021import org.kuali.ole.module.purap.PurapConstants; 022import org.kuali.ole.module.purap.PurapConstants.CorrectionReceivingDocumentStrings; 023import org.kuali.ole.module.purap.PurapConstants.PREQDocumentsStrings; 024import org.kuali.ole.module.purap.PurapKeyConstants; 025import org.kuali.ole.module.purap.PurapPropertyConstants; 026import org.kuali.ole.module.purap.businessobject.LineItemReceivingItem; 027import org.kuali.ole.module.purap.document.LineItemReceivingDocument; 028import org.kuali.ole.module.purap.document.PurchaseOrderDocument; 029import org.kuali.ole.module.purap.document.ReceivingDocument; 030import org.kuali.ole.module.purap.document.service.PurchaseOrderService; 031import org.kuali.ole.module.purap.document.service.ReceivingService; 032import org.kuali.ole.module.purap.document.validation.event.AddReceivingItemEvent; 033import org.kuali.ole.module.purap.util.ReceivingQuestionCallback; 034import org.kuali.ole.sys.OLEConstants; 035import org.kuali.ole.sys.OLEKeyConstants; 036import org.kuali.ole.sys.OLEPropertyConstants; 037import org.kuali.ole.sys.context.SpringContext; 038import org.kuali.rice.core.api.config.property.ConfigurationService; 039import org.kuali.rice.core.api.util.type.KualiDecimal; 040import org.kuali.rice.kew.api.exception.WorkflowException; 041import org.kuali.rice.kim.api.KimConstants; 042import org.kuali.rice.kns.question.ConfirmationQuestion; 043import org.kuali.rice.kns.service.DocumentHelperService; 044import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 045import org.kuali.rice.krad.service.KualiRuleService; 046import org.kuali.rice.krad.util.GlobalVariables; 047import org.kuali.rice.krad.util.KRADConstants; 048import org.kuali.rice.krad.util.ObjectUtils; 049import org.kuali.rice.krad.util.UrlFactory; 050 051import javax.servlet.http.HttpServletRequest; 052import javax.servlet.http.HttpServletResponse; 053import java.util.HashMap; 054import java.util.List; 055import java.util.Properties; 056 057public class LineItemReceivingAction extends ReceivingBaseAction { 058 059 @Override 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(OLEPropertyConstants.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, OLEKeyConstants.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, OLEKeyConstants.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(OLEConstants.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, KRADConstants.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(OLEConstants.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(OLEConstants.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 @Override 152 public ReceivingDocument doPostQuestion(ReceivingDocument document, String noteText) throws Exception { 153 //mark question completed 154 this.setQuestionComplete(true); 155 this.setCorrectionDocumentCreationNoteText(noteText); 156 return document; 157 } 158 159 @Override 160 public boolean isQuestionComplete() { 161 return this.questionComplete; 162 } 163 164 @Override 165 public void setQuestionComplete(boolean questionComplete) { 166 this.questionComplete = questionComplete; 167 } 168 169 @Override 170 public String getCorrectionDocumentCreationNoteText() { 171 return correctionDocumentnoteText; 172 } 173 174 @Override 175 public void setCorrectionDocumentCreationNoteText(String noteText) { 176 correctionDocumentnoteText = noteText; 177 } 178 }; 179 180 //ask question 181 ActionForward forward = askQuestionWithInput(mapping, form, request, response, CorrectionReceivingDocumentStrings.NOTE_QUESTION, CorrectionReceivingDocumentStrings.NOTE_PREFIX, operation, PurapKeyConstants.MESSAGE_RECEIVING_CORRECTION_NOTE, callback); 182 183 //if question asked is complete, then route 184 if (callback.isQuestionComplete()) { 185 186 //set parameters 187 String basePath = getApplicationBaseUrl(); 188 String methodToCallDocHandler = "docHandler"; 189 String methodToCallReceivingCorrection = "initiate"; 190 191 Properties parameters = new Properties(); 192 parameters.put(OLEConstants.DISPATCH_REQUEST_PARAMETER, methodToCallDocHandler); 193 parameters.put(OLEConstants.PARAMETER_COMMAND, methodToCallReceivingCorrection); 194 parameters.put(OLEConstants.DOCUMENT_TYPE_NAME, "RCVC"); 195 parameters.put("receivingLineDocId", document.getDocumentHeader().getDocumentNumber()); 196 parameters.put(PurapConstants.CorrectionReceivingDocumentStrings.CORRECTION_RECEIVING_CREATION_NOTE_PARAMETER, callback.getCorrectionDocumentCreationNoteText()); 197 198 //create url 199 String receivingCorrectionUrl = UrlFactory.parameterizeUrl(basePath + "/" + "purapCorrectionReceiving.do", parameters); 200 //create forward 201 forward = new ActionForward(receivingCorrectionUrl, true); 202 } 203 204 return forward; 205 206 } 207 208 public ActionForward clearInitFields(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 209 LineItemReceivingForm rlForm = (LineItemReceivingForm) form; 210 LineItemReceivingDocument rlDocument = (LineItemReceivingDocument) rlForm.getDocument(); 211 rlDocument.clearInitFields(rlForm.isFromPurchaseOrder()); 212 213 return mapping.findForward(OLEConstants.MAPPING_BASIC); 214 } 215 216 protected ActionForward performDuplicateReceivingLineCheck(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, LineItemReceivingDocument lineItemReceivingDocument) throws Exception { 217 ActionForward forward = null; 218 HashMap<String, String> duplicateMessages = SpringContext.getBean(ReceivingService.class).receivingLineDuplicateMessages(lineItemReceivingDocument); 219 if (duplicateMessages != null && !duplicateMessages.isEmpty()) { 220 Object question = request.getParameter(OLEConstants.QUESTION_INST_ATTRIBUTE_NAME); 221 if (question == null) { 222 223 return this.performQuestionWithoutInput(mapping, form, request, response, PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION, duplicateMessages.get(PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION), OLEConstants.CONFIRMATION_QUESTION, OLEConstants.ROUTE_METHOD, ""); 224 } 225 226 Object buttonClicked = request.getParameter(OLEConstants.QUESTION_CLICKED_BUTTON); 227 if ((PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { 228 forward = mapping.findForward(OLEConstants.MAPPING_BASIC); 229 } 230 } 231 232 return forward; 233 } 234 235 /** 236 * Add a new item to the document. 237 * 238 * @param mapping An ActionMapping 239 * @param form An ActionForm 240 * @param request The HttpServletRequest 241 * @param response The HttpServletResponse 242 * @return An ActionForward 243 * @throws Exception 244 */ 245 public ActionForward addItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 246 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 247 LineItemReceivingItem item = lineItemReceivingForm.getNewLineItemReceivingItemLine(); 248 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 249 250 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AddReceivingItemEvent(PurapPropertyConstants.NEW_LINE_ITEM_RECEIVING_ITEM_LINE, lineItemReceivingDocument, item)); 251 if (rulePassed) { 252 lineItemReceivingForm.setHideAddUnorderedItem(true); // hide the add unordered item line once an item is added 253 item = lineItemReceivingForm.getAndResetNewReceivingItemLine(); 254 lineItemReceivingDocument.addItem(item); 255 //TODO: we need to set the line number correctly to match up to PO 256 } 257 258 return mapping.findForward(OLEConstants.MAPPING_BASIC); 259 } 260 261 /** 262 * For each item, it's quantity received value is set to zero. 263 * 264 * @param mapping 265 * @param form 266 * @param request 267 * @param response 268 * @return 269 * @throws Exception 270 */ 271 public ActionForward clearQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 272 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 273 274 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 275 276 for (LineItemReceivingItem item : (List<LineItemReceivingItem>) lineItemReceivingDocument.getItems()) { 277 item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); 278 } 279 280 return mapping.findForward(OLEConstants.MAPPING_BASIC); 281 } 282 283 /** 284 * For each item, loads total order quantity minus prior received quantity into total received quantity. 285 * 286 * @param mapping 287 * @param form 288 * @param request 289 * @param response 290 * @return 291 * @throws Exception 292 */ 293 public ActionForward loadQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 294 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 295 296 LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); 297 298 for (LineItemReceivingItem item : (List<LineItemReceivingItem>) lineItemReceivingDocument.getItems()) { 299 if (item.isOrderedItem()) { 300 if (item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()).isGreaterEqual(KualiDecimal.ZERO)) { 301 item.setItemReceivedTotalQuantity(item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity())); 302 } else { 303 item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); 304 } 305 } 306 } 307 308 return mapping.findForward(OLEConstants.MAPPING_BASIC); 309 } 310 311 /** 312 * Gives a warning before showing the add new unordered line item; if the user confirms the action, proceeds; 313 * otherwise cancels the action and returns to the current LineItemReceivingDocument. 314 * 315 * @param mapping An ActionMapping 316 * @param form An ActionForm 317 * @param request The HttpServletRequest 318 * @param response The HttpServletResponse 319 * @return An ActionForward 320 * @throws Exception 321 */ 322 public ActionForward showAddUnorderedItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 323 LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; 324 325 boolean shouldGiveWarning = lineItemReceivingForm.shouldGiveAddUnorderedItemWarning(); 326 if (!shouldGiveWarning) { 327 lineItemReceivingForm.setHideAddUnorderedItem(false); 328 return mapping.findForward(OLEConstants.MAPPING_BASIC); 329 } 330 331 String msgkey = PurapKeyConstants.WARNING_RECEIVING_LINEITEM_ADD_UNORDERED; 332 String msgtxt = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(msgkey); 333 Object question = request.getParameter(OLEConstants.QUESTION_INST_ATTRIBUTE_NAME); 334 335 if (question == null) { 336 return performQuestionWithoutInput(mapping, form, request, response, msgkey, msgtxt, OLEConstants.CONFIRMATION_QUESTION, "showAddUnorderedItem", ""); 337 } 338 339 Object buttonClicked = request.getParameter(OLEConstants.QUESTION_CLICKED_BUTTON); 340 if ((msgkey.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) { 341 lineItemReceivingForm.setHideAddUnorderedItem(false); 342 } 343 344 return mapping.findForward(OLEConstants.MAPPING_BASIC); 345 } 346 347}