View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.module.purap.document.web.struts;
20  
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Properties;
24  
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  
28  import org.apache.struts.action.ActionForm;
29  import org.apache.struts.action.ActionForward;
30  import org.apache.struts.action.ActionMapping;
31  import org.kuali.kfs.module.purap.PurapConstants;
32  import org.kuali.kfs.module.purap.PurapConstants.CorrectionReceivingDocumentStrings;
33  import org.kuali.kfs.module.purap.PurapConstants.PREQDocumentsStrings;
34  import org.kuali.kfs.module.purap.PurapKeyConstants;
35  import org.kuali.kfs.module.purap.PurapPropertyConstants;
36  import org.kuali.kfs.module.purap.businessobject.LineItemReceivingItem;
37  import org.kuali.kfs.module.purap.document.LineItemReceivingDocument;
38  import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
39  import org.kuali.kfs.module.purap.document.ReceivingDocument;
40  import org.kuali.kfs.module.purap.document.service.PurchaseOrderService;
41  import org.kuali.kfs.module.purap.document.service.ReceivingService;
42  import org.kuali.kfs.module.purap.document.validation.event.AddReceivingItemEvent;
43  import org.kuali.kfs.module.purap.util.ReceivingQuestionCallback;
44  import org.kuali.kfs.sys.KFSConstants;
45  import org.kuali.kfs.sys.KFSKeyConstants;
46  import org.kuali.kfs.sys.KFSPropertyConstants;
47  import org.kuali.kfs.sys.context.SpringContext;
48  import org.kuali.rice.core.api.config.property.ConfigurationService;
49  import org.kuali.rice.core.api.util.type.KualiDecimal;
50  import org.kuali.rice.kew.api.exception.WorkflowException;
51  import org.kuali.rice.kim.api.KimConstants;
52  import org.kuali.rice.kns.question.ConfirmationQuestion;
53  import org.kuali.rice.kns.service.DocumentHelperService;
54  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
55  import org.kuali.rice.krad.service.KualiRuleService;
56  import org.kuali.rice.krad.util.GlobalVariables;
57  import org.kuali.rice.krad.util.KRADConstants;
58  import org.kuali.rice.krad.util.ObjectUtils;
59  import org.kuali.rice.krad.util.UrlFactory;
60  
61  public class LineItemReceivingAction extends ReceivingBaseAction {
62  
63      @Override
64      protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
65  
66          super.createDocument(kualiDocumentFormBase);
67  
68          LineItemReceivingForm rlf = (LineItemReceivingForm)kualiDocumentFormBase;
69          LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument();
70  
71          //set identifier from form value
72          rlDoc.setPurchaseOrderIdentifier( rlf.getPurchaseOrderId() );
73  
74          rlDoc.initiateDocument();
75  
76      }
77  
78      public ActionForward continueReceivingLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
79          LineItemReceivingForm rlf = (LineItemReceivingForm)form;
80          LineItemReceivingDocument rlDoc = (LineItemReceivingDocument)rlf.getDocument();
81  
82          GlobalVariables.getMessageMap().clearErrorPath();
83          GlobalVariables.getMessageMap().addToErrorPath(KFSPropertyConstants.DOCUMENT);
84          boolean valid = true;
85          boolean poNotNull = true;
86  
87          //check for a po id
88          if (ObjectUtils.isNull(rlDoc.getPurchaseOrderIdentifier())) {
89              GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, KFSKeyConstants.ERROR_REQUIRED, PREQDocumentsStrings.PURCHASE_ORDER_ID);
90              poNotNull = false;
91          }
92  
93          if (ObjectUtils.isNull(rlDoc.getShipmentReceivedDate())) {
94              GlobalVariables.getMessageMap().putError(PurapPropertyConstants.SHIPMENT_RECEIVED_DATE, KFSKeyConstants.ERROR_REQUIRED, PurapConstants.LineItemReceivingDocumentStrings.VENDOR_DATE);
95          }
96  
97          //exit early as the po is null, no need to proceed further until this is taken care of
98          if(poNotNull == false){
99              return mapping.findForward(KFSConstants.MAPPING_BASIC);
100         }
101 
102         PurchaseOrderDocument po = SpringContext.getBean(PurchaseOrderService.class).getCurrentPurchaseOrder(rlDoc.getPurchaseOrderIdentifier());
103         if (ObjectUtils.isNotNull(po)) {
104             // 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
105             rlDoc.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
106 
107             //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)
108             if (!SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(rlDoc).isAuthorizedByTemplate(rlDoc, KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, GlobalVariables.getUserSession().getPrincipalId())) {
109                 throw buildAuthorizationException("initiate document", rlDoc);
110             }
111         }else{
112             GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_PURCHASE_ORDER_NOT_EXIST);
113             return mapping.findForward(KFSConstants.MAPPING_BASIC);
114         }
115 
116         //perform duplicate check
117         ActionForward forward = performDuplicateReceivingLineCheck(mapping, form, request, response, rlDoc);
118         if( forward != null ){
119             return forward;
120         }
121 
122         if (!SpringContext.getBean(ReceivingService.class).isPurchaseOrderActiveForLineItemReceivingDocumentCreation(rlDoc.getPurchaseOrderIdentifier())){
123             GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_PO_NOT_ACTIVE, rlDoc.getPurchaseOrderIdentifier().toString());
124             valid &= false;
125         }
126 
127         if( SpringContext.getBean(ReceivingService.class).canCreateLineItemReceivingDocument(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber()) == false){
128             String inProcessDocNum = "";
129             List<String> inProcessDocNumbers = SpringContext.getBean(ReceivingService.class).getLineItemReceivingDocumentNumbersInProcessForPurchaseOrder(rlDoc.getPurchaseOrderIdentifier(), rlDoc.getDocumentNumber());
130             if (!inProcessDocNumbers.isEmpty()) {    // should not be empty if we reach this point
131                 inProcessDocNum = inProcessDocNumbers.get(0);
132             }
133             GlobalVariables.getMessageMap().putError(PurapPropertyConstants.PURCHASE_ORDER_IDENTIFIER, PurapKeyConstants.ERROR_RECEIVING_LINE_DOCUMENT_ACTIVE_FOR_PO, inProcessDocNum, rlDoc.getPurchaseOrderIdentifier().toString());
134             valid &= false;
135         }
136 
137         //populate and save Receiving Line Document from Purchase Order, only if we passed all the rules
138         if(valid){
139             SpringContext.getBean(ReceivingService.class).populateAndSaveLineItemReceivingDocument(rlDoc);
140         }
141 
142         return mapping.findForward(KFSConstants.MAPPING_BASIC);
143     }
144 
145     public ActionForward createReceivingCorrection(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
146         LineItemReceivingForm rlForm = (LineItemReceivingForm) form;
147         LineItemReceivingDocument document = (LineItemReceivingDocument) rlForm.getDocument();
148 
149         String operation = "AddCorrectionNote ";
150 
151         ReceivingQuestionCallback callback = new ReceivingQuestionCallback() {
152             public boolean questionComplete = false;
153             protected String correctionDocumentnoteText;
154 
155             @Override
156             public ReceivingDocument doPostQuestion(ReceivingDocument document, String noteText) throws Exception {
157                 //mark question completed
158                 this.setQuestionComplete(true);
159                 this.setCorrectionDocumentCreationNoteText(noteText);
160                 return document;
161             }
162 
163             @Override
164             public boolean isQuestionComplete(){
165                 return this.questionComplete;
166             }
167 
168             @Override
169             public void setQuestionComplete(boolean questionComplete){
170                 this.questionComplete = questionComplete;
171             }
172 
173             @Override
174             public String getCorrectionDocumentCreationNoteText() {
175                 return correctionDocumentnoteText;
176             }
177 
178             @Override
179             public void setCorrectionDocumentCreationNoteText(String noteText) {
180                 correctionDocumentnoteText = noteText;
181             }
182         };
183 
184         //ask question
185         ActionForward forward = askQuestionWithInput(mapping, form, request, response, CorrectionReceivingDocumentStrings.NOTE_QUESTION, CorrectionReceivingDocumentStrings.NOTE_PREFIX, operation, PurapKeyConstants.MESSAGE_RECEIVING_CORRECTION_NOTE, callback);
186 
187         //if question asked is complete, then route
188         if(callback.isQuestionComplete()){
189 
190             //set parameters
191             String basePath = getApplicationBaseUrl();
192             String methodToCallDocHandler = "docHandler";
193             String methodToCallReceivingCorrection = "initiate";
194 
195             Properties parameters = new Properties();
196             parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCallDocHandler);
197             parameters.put(KFSConstants.PARAMETER_COMMAND, methodToCallReceivingCorrection);
198             parameters.put(KFSConstants.DOCUMENT_TYPE_NAME, "RCVC");
199             parameters.put("receivingLineDocId", document.getDocumentHeader().getDocumentNumber() );
200             parameters.put(PurapConstants.CorrectionReceivingDocumentStrings.CORRECTION_RECEIVING_CREATION_NOTE_PARAMETER, callback.getCorrectionDocumentCreationNoteText());
201 
202             //create url
203             String receivingCorrectionUrl = UrlFactory.parameterizeUrl(basePath + "/" + "purapCorrectionReceiving.do", parameters);
204             //create forward
205             forward = new ActionForward(receivingCorrectionUrl, true);
206         }
207 
208         return forward;
209 
210     }
211 
212     public ActionForward clearInitFields(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
213         LineItemReceivingForm rlForm = (LineItemReceivingForm) form;
214         LineItemReceivingDocument rlDocument = (LineItemReceivingDocument) rlForm.getDocument();
215         rlDocument.clearInitFields(rlForm.isFromPurchaseOrder());
216 
217         return mapping.findForward(KFSConstants.MAPPING_BASIC);
218     }
219 
220     protected ActionForward performDuplicateReceivingLineCheck(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, LineItemReceivingDocument lineItemReceivingDocument) throws Exception {
221         ActionForward forward = null;
222         HashMap<String, String> duplicateMessages = SpringContext.getBean(ReceivingService.class).receivingLineDuplicateMessages(lineItemReceivingDocument);
223         if (duplicateMessages != null && !duplicateMessages.isEmpty()) {
224             Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
225             if (question == null) {
226 
227                 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, "");
228             }
229 
230             Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
231             if ((PurapConstants.LineItemReceivingDocumentStrings.DUPLICATE_RECEIVING_LINE_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) {
232                 forward = mapping.findForward(KFSConstants.MAPPING_BASIC);
233             }
234         }
235 
236         return forward;
237     }
238     /**
239      * Add a new item to the document.
240      *
241      * @param mapping An ActionMapping
242      * @param form An ActionForm
243      * @param request The HttpServletRequest
244      * @param response The HttpServletResponse
245      * @throws Exception
246      * @return An ActionForward
247      */
248     public ActionForward addItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
249         LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form;
250         LineItemReceivingItem item = lineItemReceivingForm.getNewLineItemReceivingItemLine();
251         LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument();
252 
253         boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AddReceivingItemEvent(PurapPropertyConstants.NEW_LINE_ITEM_RECEIVING_ITEM_LINE, lineItemReceivingDocument, item));
254         if (rulePassed) {
255             lineItemReceivingForm.setHideAddUnorderedItem(true); // hide the add unordered item line once an item is added
256             item = lineItemReceivingForm.getAndResetNewReceivingItemLine();
257             lineItemReceivingDocument.addItem(item);
258             //TODO: we need to set the line number correctly to match up to PO
259         }
260 
261         return mapping.findForward(KFSConstants.MAPPING_BASIC);
262     }
263 
264     /**
265      * For each item, it's quantity received value is set to zero.
266      *
267      * @param mapping
268      * @param form
269      * @param request
270      * @param response
271      * @return
272      * @throws Exception
273      */
274     public ActionForward clearQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
275         LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form;
276 
277         LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument();
278 
279         for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){
280             item.setItemReceivedTotalQuantity(KualiDecimal.ZERO);
281         }
282 
283         return mapping.findForward(KFSConstants.MAPPING_BASIC);
284     }
285 
286     /**
287      * For each item, loads total order quantity minus prior received quantity into total received quantity.
288      *
289      * @param mapping
290      * @param form
291      * @param request
292      * @param response
293      * @return
294      * @throws Exception
295      */
296     public ActionForward loadQty(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
297         LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm) form;
298 
299         LineItemReceivingDocument lineItemReceivingDocument = (LineItemReceivingDocument) lineItemReceivingForm.getDocument();
300 
301         for(LineItemReceivingItem item : (List <LineItemReceivingItem>)lineItemReceivingDocument.getItems()){
302             if (item.isOrderedItem()){
303                 if( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()).isGreaterEqual(KualiDecimal.ZERO)  ){
304                     item.setItemReceivedTotalQuantity( item.getItemOrderedQuantity().subtract(item.getItemReceivedPriorQuantity()) );
305                 }else{
306                     item.setItemReceivedTotalQuantity(KualiDecimal.ZERO);
307                 }
308             }
309         }
310 
311         return mapping.findForward(KFSConstants.MAPPING_BASIC);
312     }
313 
314     /**
315      * Gives a warning before showing the add new unordered line item; if the user confirms the action, proceeds;
316      * otherwise cancels the action and returns to the current LineItemReceivingDocument.
317      *
318      * @param mapping An ActionMapping
319      * @param form An ActionForm
320      * @param request The HttpServletRequest
321      * @param response The HttpServletResponse
322      * @throws Exception
323      * @return An ActionForward
324      */
325     public ActionForward showAddUnorderedItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
326         LineItemReceivingForm lineItemReceivingForm = (LineItemReceivingForm)form;
327 
328         boolean shouldGiveWarning = lineItemReceivingForm.shouldGiveAddUnorderedItemWarning();
329         if (!shouldGiveWarning) {
330             lineItemReceivingForm.setHideAddUnorderedItem(false);
331             return mapping.findForward(KFSConstants.MAPPING_BASIC);
332         }
333 
334         String msgkey = PurapKeyConstants.WARNING_RECEIVING_LINEITEM_ADD_UNORDERED;
335         String msgtxt = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(msgkey);
336         Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
337 
338         if (question == null) {
339             return performQuestionWithoutInput(mapping, form, request, response, msgkey, msgtxt, KFSConstants.CONFIRMATION_QUESTION, "showAddUnorderedItem", "");
340         }
341 
342         Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
343         if ((msgkey.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
344             lineItemReceivingForm.setHideAddUnorderedItem(false);
345         }
346 
347         return mapping.findForward(KFSConstants.MAPPING_BASIC);
348     }
349 
350 }