/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.purap.document.web.struts; import java.util.HashMap; import java.util.List; import java.util.Properties; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.kuali.kfs.module.purap.PurapConstants; import org.kuali.kfs.module.purap.PurapConstants.CorrectionReceivingDocumentStrings; import org.kuali.kfs.module.purap.PurapConstants.PREQDocumentsStrings; import org.kuali.kfs.module.purap.PurapKeyConstants; import org.kuali.kfs.module.purap.PurapPropertyConstants; import org.kuali.kfs.module.purap.businessobject.LineItemReceivingItem; import org.kuali.kfs.module.purap.document.LineItemReceivingDocument; import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; import org.kuali.kfs.module.purap.document.ReceivingDocument; import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; import org.kuali.kfs.module.purap.document.service.ReceivingService; import org.kuali.kfs.module.purap.document.validation.event.AddReceivingItemEvent; import org.kuali.kfs.module.purap.util.ReceivingQuestionCallback; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.core.api.config.property.ConfigurationService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kns.question.ConfirmationQuestion; import org.kuali.rice.kns.service.DocumentHelperService; import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; import org.kuali.rice.krad.service.KualiRuleService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.KRADConstants; import org.kuali.rice.krad.util.ObjectUtils; import org.kuali.rice.krad.util.UrlFactory; public class LineItemReceivingAction extends ReceivingBaseAction { @Override protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { super.createDocument(kualiDocumentFormBase); LineItemReceivingForm rlf = (LineItemReceivingForm)kualiDocumentFormBase; LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument(); //set identifier from form value rlDoc.setPurchaseOrderIdentifier( rlf.getPurchaseOrderId() ); rlDoc.initiateDocument(); } public ActionForward continueReceivingLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm rlf = (LineItemReceivingForm)form; LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument(); GlobalVariables.getMessageMap().clearErrorPath(); GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.DOCUMENT); boolean valid = true; boolean poNotNull = true; //check for a po id if (ObjectUtils.isNull(rlDoc.getPurchaseOrderIdentifier())) { GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, KFSKeyConstants.ERROR_REQUIRED, PREQDocumentsStrings.PURCHASE_ORDER_ID); poNotNull = false; } if (ObjectUtils.isNull(rlDoc.getShipmentReceivedDate())) { GlobalVariables.getMessageMap().putError(PurapPropertyConstants.SHIPMENT_RECEIVED_DATE, KFSKeyConstants.ERROR_REQUIRED, PurapConstants.LineItemReceivingDocumentStrings.VENDOR_DATE); } //exit early as the po is null, no need to proceed further until this is taken care of if(poNotNull == false){ return mapping.findForward(KFSConstants.MAPPING_BASIC); } PurchaseOrderDocument po = SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(rlDoc.getPurchaseOrderIdentifier()); if (ObjectUtils.isNotNull(po)) { // 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 rlDoc.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier()); //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) if (!SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(rlDoc).isAuthorizedByTemplate(rlDoc, KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, GlobalVariables.getUserSession().getPrincipalId())) { throw buildAuthorizationException("initiate document", rlDoc); } }else{ GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_PURCHASE_ORDER_NOT_EXIST); return mapping.findForward(KFSConstants.MAPPING_BASIC); } //perform duplicate check ActionForward forward = performDuplicateReceivingLineCheck(mapping, form, request, response, rlDoc); if( forward != null ){ return forward; } if (!SpringContext.getBean(ReceivingService.class).isPurchaseOrderActiveForLineItemReceivingDocumentCreation(rlDoc.getPurchaseOrderIdentifier())){ GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_PO_NOT_ACTIVE, rlDoc.getPurchaseOrderIdentifier().toString()); valid &= false; } if( SpringContext.getBean(ReceivingService.class).canCreateLineItemReceivingDocument(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber()) == false){ String inProcessDocNum = ""; List<String> inProcessDocNumbers = SpringContext.getBean(ReceivingService.class).getLineItemReceivingDocumentNumbersInProcessForPurchaseOrder(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber()); if (!inProcessDocNumbers.isEmpty()) { // should not be empty if we reach this point inProcessDocNum = inProcessDocNumbers.get(0); } GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_ACTIVE_FOR_PO, inProcessDocNum, rlDoc.getPurchaseOrderIdentifier().toString()); valid &= false; } //populate and save Receiving Line Document from Purchase Order, only if we passed all the rules if(valid){ SpringContext.getBean(ReceivingService.class).populateAndSaveLineItemReceivingDocument(rlDoc); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } public ActionForward createReceivingCorrection(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm rlForm = (LineItemReceivingForm) form; LineItemReceivingDocument document = (LineItemReceivingDocument) rlForm.getDocument(); String operation = "AddCorrectionNote "; ReceivingQuestionCallback callback = new ReceivingQuestionCallback() { public boolean questionComplete = false; protected String correctionDocumentnoteText; @Override public ReceivingDocument doPostQuestion(ReceivingDocument document, String noteText) throws Exception { //mark question completed this.setQuestionComplete(true); this.setCorrectionDocumentCreationNoteText(noteText); return document; } @Override public boolean isQuestionComplete(){ return this.questionComplete; } @Override public void setQuestionComplete(boolean questionComplete){ this.questionComplete = questionComplete; } @Override public String getCorrectionDocumentCreationNoteText() { return correctionDocumentnoteText; } @Override public void setCorrectionDocumentCreationNoteText(String noteText) { correctionDocumentnoteText = noteText; } }; //ask question ActionForward forward = askQuestionWithInput(mapping, form, request, response, CorrectionReceivingDocumentStrings.NOTE_QUESTION, CorrectionReceivingDocumentStrings.NOTE_PREFIX, operation, PurapKeyConstants.MESSAGE_RECEIVING_CORRECTION_NOTE, callback); //if question asked is complete, then route if(callback.isQuestionComplete()){ //set parameters String basePath = getApplicationBaseUrl(); String methodToCallDocHandler = "docHandler"; String methodToCallReceivingCorrection = "initiate"; Properties parameters = new Properties(); parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCallDocHandler); parameters.put(KFSConstants.PARAMETER_COMMAND, methodToCallReceivingCorrection); parameters.put(KFSConstants.DOCUMENT_TYPE_NAME, "RCVC"); parameters.put("receivingLineDocId", document.getDocumentHeader().getDocumentNumber() ); parameters.put(PurapConstants.CorrectionReceivingDocumentStrings.CORRECTION_RECEIVING_CREATION_NOTE_PARAMETER, callback.getCorrectionDocumentCreationNoteText()); //create url String receivingCorrectionUrl = UrlFactory.parameterizeUrl(basePath + "/" + "purapCorrectionReceiving.do", parameters); //create forward forward = new ActionForward(receivingCorrectionUrl, true); } return forward; } public ActionForward clearInitFields(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm rlForm = (LineItemReceivingForm) form; LineItemReceivingDocument rlDocument = (LineItemReceivingDocument) rlForm.getDocument(); rlDocument.clearInitFields(rlForm.isFromPurchaseOrder()); return mapping.findForward(KFSConstants.MAPPING_BASIC); } protected ActionForward performDuplicateReceivingLineCheck(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, LineItemReceivingDocument lineItemReceivingDocument) throws Exception { ActionForward forward = null; HashMap<String, String> duplicateMessages = SpringContext.getBean(ReceivingService.class).receivingLineDuplicateMessages(lineItemReceivingDocument); if (duplicateMessages != null && !duplicateMessages.isEmpty()) { Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME); if (question == null) { 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, ""); } Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); if ((PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { forward = mapping.findForward(KFSConstants.MAPPING_BASIC); } } return forward; } /** * Add a new item to the document. * * @param mapping An ActionMapping * @param form An ActionForm * @param request The HttpServletRequest * @param response The HttpServletResponse * @throws Exception * @return An ActionForward */ public ActionForward addItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; LineItemReceivingItem item = lineItemReceivingForm.getNewLineItemReceivingItemLine(); LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AddReceivingItemEvent(PurapPropertyConstants.NEW_LINE_ITEM_RECEIVING_ITEM_LINE, lineItemReceivingDocument, item)); if (rulePassed) { lineItemReceivingForm.setHideAddUnorderedItem(true); // hide the add unordered item line once an item is added item = lineItemReceivingForm.getAndResetNewReceivingItemLine(); lineItemReceivingDocument.addItem(item); //TODO: we need to set the line number correctly to match up to PO } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * For each item, it's quantity received value is set to zero. * * @param mapping * @param form * @param request * @param response * @return * @throws Exception */ public ActionForward clearQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){ item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * For each item, loads total order quantity minus prior received quantity into total received quantity. * * @param mapping * @param form * @param request * @param response * @return * @throws Exception */ public ActionForward loadQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form; LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument(); for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){ if (item.isOrderedItem()){ if( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()).isGreaterEqual(KualiDecimal.ZERO) ){ item.setItemReceivedTotalQuantity( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()) ); }else{ item.setItemReceivedTotalQuantity(KualiDecimal.ZERO); } } } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * Gives a warning before showing the add new unordered line item; if the user confirms the action, proceeds; * otherwise cancels the action and returns to the current LineItemReceivingDocument. * * @param mapping An ActionMapping * @param form An ActionForm * @param request The HttpServletRequest * @param response The HttpServletResponse * @throws Exception * @return An ActionForward */ public ActionForward showAddUnorderedItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm)form; boolean shouldGiveWarning = lineItemReceivingForm.shouldGiveAddUnorderedItemWarning(); if (!shouldGiveWarning) { lineItemReceivingForm.setHideAddUnorderedItem(false); return mapping.findForward(KFSConstants.MAPPING_BASIC); } String msgkey = PurapKeyConstants.WARNING_RECEIVING_LINEITEM_ADD_UNORDERED; String msgtxt = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(msgkey); Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME); if (question == null) { return performQuestionWithoutInput(mapping, form, request, response, msgkey, msgtxt, KFSConstants.CONFIRMATION_QUESTION, "showAddUnorderedItem", ""); } Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); if ((msgkey.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) { lineItemReceivingForm.setHideAddUnorderedItem(false); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } }