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.validation.impl; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.kuali.kfs.module.purap.PurapConstants; 020 import org.kuali.kfs.module.purap.PurapKeyConstants; 021 import org.kuali.kfs.module.purap.businessobject.PurApItem; 022 import org.kuali.kfs.module.purap.businessobject.PurchasingItemBase; 023 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 024 import org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocument; 025 import org.kuali.kfs.module.purap.document.PurchasingDocument; 026 import org.kuali.kfs.module.purap.document.RequisitionDocument; 027 import org.kuali.kfs.module.purap.document.service.PurapService; 028 import org.kuali.kfs.module.purap.document.web.struts.PurchasingFormBase; 029 import org.kuali.kfs.sys.KFSConstants; 030 import org.kuali.kfs.sys.context.SpringContext; 031 import org.kuali.kfs.sys.document.AmountTotaling; 032 import org.kuali.rice.kns.document.Document; 033 import org.kuali.rice.kns.rules.PromptBeforeValidationBase; 034 import org.kuali.rice.kns.service.KualiConfigurationService; 035 import org.kuali.rice.kns.util.GlobalVariables; 036 import org.kuali.rice.kns.util.KualiDecimal; 037 import org.kuali.rice.kns.util.ObjectUtils; 038 039 /** 040 * Business Prerules applicable to purchase order document. 041 */ 042 public class PurchaseOrderDocumentPreRules extends PurchasingDocumentPreRulesBase { 043 044 /** 045 * Overrides the method in PromptBeforeValidationBase to also invoke the confirmNotToExceedOverride if the PromptBeforeValidationEvent is 046 * blank and the question matches with the OverrideNotToExceed 047 * 048 * @param document The purchase order document upon which we're performing the prerules logic. 049 * @return boolean true if it passes the pre rules conditions. 050 * @see org.kuali.rice.kns.rules.PromptBeforeValidationBase#doRules(org.kuali.rice.kns.document.Document) 051 */ 052 @Override 053 public boolean doPrompts(Document document) { 054 055 boolean preRulesOK = true; 056 057 PurchaseOrderDocument purchaseOrderDocument = (PurchaseOrderDocument) document; 058 059 if (StringUtils.isBlank(event.getQuestionContext()) || StringUtils.equals(question, PurapConstants.PO_OVERRIDE_NOT_TO_EXCEED_QUESTION)) { 060 preRulesOK &= confirmNotToExceedOverride(purchaseOrderDocument); 061 } 062 063 if (isDocumentInStateToReceiveNextFyWarning(purchaseOrderDocument) && 064 (StringUtils.isBlank(event.getQuestionContext()) || StringUtils.equals(question, PurapConstants.PO_NEXT_FY_WARNING))) { 065 preRulesOK &= confirmNextFYPriorToApoAllowedDate(purchaseOrderDocument); 066 } 067 068 if (!purchaseOrderDocument.isUseTaxIndicator()){ 069 preRulesOK &= checkForTaxRecalculation(purchaseOrderDocument); 070 } 071 072 return preRulesOK; 073 } 074 075 /** 076 * Give next FY warning if the PO status is "In Process" or "Awaiting Purchasing Review" 077 * 078 * @param poDocument 079 * @return boolean 080 */ 081 protected boolean isDocumentInStateToReceiveNextFyWarning(PurchaseOrderDocument poDocument){ 082 return (PurapConstants.PurchaseOrderStatuses.IN_PROCESS.equals(poDocument.getStatusCode()) || 083 PurapConstants.PurchaseOrderStatuses.AWAIT_PURCHASING_REVIEW.equals(poDocument.getStatusCode())); 084 } 085 086 /** 087 * Checks whether the 'Not-to-exceed' amount has been exceeded by the purchase order total dollar limit. If so, it 088 * prompts the user for confirmation. 089 * 090 * @param purchaseOrderDocument The current PurchaseOrderDocument 091 * @return True if the 'Not-to-exceed' amount is to be overridden or if the total dollar amount is less than the purchase order 092 * total dollar limit. 093 */ 094 protected boolean confirmNotToExceedOverride(PurchaseOrderDocument purchaseOrderDocument) { 095 096 // If the total exceeds the limit, ask for confirmation. 097 if (!validateTotalDollarAmountIsLessThanPurchaseOrderTotalLimit(purchaseOrderDocument)) { 098 String questionText = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.PURCHASE_ORDER_QUESTION_OVERRIDE_NOT_TO_EXCEED); 099 100 boolean confirmOverride = super.askOrAnalyzeYesNoQuestion(PurapConstants.PO_OVERRIDE_NOT_TO_EXCEED_QUESTION, questionText); 101 102 // Set a marker to record that this method has been used. 103 if (confirmOverride && StringUtils.isBlank(event.getQuestionContext())) { 104 event.setQuestionContext(PurapConstants.PO_OVERRIDE_NOT_TO_EXCEED_QUESTION); 105 } 106 107 if (!confirmOverride) { 108 event.setActionForwardName(KFSConstants.MAPPING_BASIC); 109 110 return false; 111 } 112 } 113 114 return true; 115 } 116 117 /** 118 * Validate that if the PurchaseOrderTotalLimit is not null then the TotalDollarAmount cannot be greater than the 119 * PurchaseOrderTotalLimit. 120 * 121 * @param purDocument The purchase order document to be validated. 122 * @return True if the TotalDollarAmount is less than the PurchaseOrderTotalLimit. False otherwise. 123 */ 124 public boolean validateTotalDollarAmountIsLessThanPurchaseOrderTotalLimit(PurchasingDocument purDocument) { 125 boolean valid = true; 126 if (ObjectUtils.isNotNull(purDocument.getPurchaseOrderTotalLimit()) && ObjectUtils.isNotNull(((AmountTotaling) purDocument).getTotalDollarAmount())) { 127 KualiDecimal totalAmount = ((AmountTotaling) purDocument).getTotalDollarAmount(); 128 if (((AmountTotaling) purDocument).getTotalDollarAmount().isGreaterThan(purDocument.getPurchaseOrderTotalLimit())) { 129 valid &= false; 130 GlobalVariables.getMessageList().add(PurapKeyConstants.PO_TOTAL_GREATER_THAN_PO_TOTAL_LIMIT); 131 } 132 } 133 134 return valid; 135 } 136 137 /** 138 * If the PO is set to encumber in the next fiscal year and the PO is created before the APO allowed date, then give the user a 139 * warning that this might be a mistake. Prompt the user for confirmation that the year is set correctly both at submit and upon 140 * approval at the Purchasing Internal Review route level. 141 * 142 * @param purchaseOrderDocument The current PurchaseOrderDocument 143 * @return True if the user wants to continue with PO routing; False to send the user back to the PO for editing. 144 */ 145 protected boolean confirmNextFYPriorToApoAllowedDate(PurchaseOrderDocument poDocument) { 146 147 // If the FY is set to NEXT and today is not within APO allowed range, ask for confirmation to continue 148 if (poDocument.isPostingYearNext() && !SpringContext.getBean(PurapService.class).isTodayWithinApoAllowedRange()) { 149 String questionText = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.WARNING_PURCHASE_ORDER_ENCUMBER_NEXT_FY); 150 boolean confirmOverride = super.askOrAnalyzeYesNoQuestion(PurapConstants.PO_NEXT_FY_WARNING, questionText); 151 152 // Set a marker to record that this method has been used. 153 if (confirmOverride && StringUtils.isBlank(event.getQuestionContext())) { 154 event.setQuestionContext(PurapConstants.PO_NEXT_FY_WARNING); 155 } 156 if (!confirmOverride) { 157 event.setActionForwardName(KFSConstants.MAPPING_BASIC); 158 return false; 159 } 160 } 161 162 return true; 163 } 164 165 @Override 166 protected boolean checkCAMSWarningStatus(PurchasingAccountsPayableDocument purapDocument) { 167 return PurapConstants.CAMSWarningStatuses.PURCHASEORDER_STATUS_WARNING_NO_CAMS_DATA.contains(purapDocument.getStatusCode()); 168 } 169 170 }