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.document.AccountsPayableDocument;
022    import org.kuali.kfs.module.purap.document.service.PurapService;
023    import org.kuali.kfs.sys.KFSConstants;
024    import org.kuali.kfs.sys.context.SpringContext;
025    import org.kuali.rice.kns.document.Document;
026    import org.kuali.rice.kns.rules.PromptBeforeValidationBase;
027    import org.kuali.rice.kns.service.KualiConfigurationService;
028    
029    /**
030     * Performs prompts and other pre business rule checks for the Accounts Payable Document (and its children).
031     */
032    public abstract class AccountsPayableDocumentPreRulesBase extends PurapDocumentPreRulesBase {
033        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountsPayableDocumentPreRulesBase.class);
034    
035        public AccountsPayableDocumentPreRulesBase() {
036            super();
037        }
038    
039        /**
040         * Asks for an override if the document hasn't reached full entry and the entered amount does not
041         * match the total amount of all items.
042         * 
043         * @see org.kuali.rice.kns.rules.PromptBeforeValidationBase#doRules(org.kuali.rice.kns.document.Document)
044         */
045        @Override
046        public boolean doPrompts(Document document){
047    
048            boolean preRulesOK = true;
049    
050            AccountsPayableDocument accountsPayableDocument = (AccountsPayableDocument) document;
051    
052            // Ask the nomatch question if the document hasn't been completed.
053            if (SpringContext.getBean(PurapService.class).isFullDocumentEntryCompleted(accountsPayableDocument) == false) {
054                preRulesOK = confirmInvoiceNoMatchOverride(accountsPayableDocument);
055            }
056            else if (SpringContext.getBean(PurapService.class).isFullDocumentEntryCompleted(accountsPayableDocument)) {
057                // if past full document entry complete, then set override to true to skip validation
058                accountsPayableDocument.setUnmatchedOverride(true);
059            }
060    
061            return preRulesOK;
062        }
063    
064        /**
065         * Checks whether the invoice from the initial screen and the document invoice are mismatched. If so, it prompts the
066         * user for confirmation to proceed.
067         * 
068         * @param accountsPayableDocument - document to have its invoice/totals checked
069         * @return
070         */
071        protected boolean confirmInvoiceNoMatchOverride(AccountsPayableDocument accountsPayableDocument) {
072    
073            // If the values are mismatched, ask for confirmation.
074            if (validateInvoiceTotalsAreMismatched(accountsPayableDocument)) {
075                
076                String questionText = createInvoiceNoMatchQuestionText(accountsPayableDocument);
077                
078                boolean confirmOverride = super.askOrAnalyzeYesNoQuestion(PurapConstants.AP_OVERRIDE_INVOICE_NOMATCH_QUESTION, questionText);
079    
080                // Set a marker to record that this method has been used.
081                if (confirmOverride && StringUtils.isBlank(event.getQuestionContext())) {
082                    event.setQuestionContext(PurapConstants.AP_OVERRIDE_INVOICE_NOMATCH_QUESTION);
083                    accountsPayableDocument.setUnmatchedOverride(true);
084                }
085    
086                if (!confirmOverride) {
087                    event.setActionForwardName(KFSConstants.MAPPING_BASIC);
088                    return false;
089                }
090            }
091    
092            return true;
093        }
094    
095        /**
096         * Creates the text for the invoice no match question being asked of the user.
097         * 
098         * @param accountsPayableDocument - to be used by overriding method.
099         * @return
100         */
101        public String createInvoiceNoMatchQuestionText(AccountsPayableDocument accountsPayableDocument){
102    
103            String questionText = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(PurapKeyConstants.AP_QUESTION_CONFIRM_INVOICE_MISMATCH); 
104            questionText = StringUtils.replace(questionText, "{0}", getDocumentName());
105            
106            return questionText;        
107        }
108        
109        /**
110         * Determines if the amount entered on the init tab is mismatched with the grand total of the document.
111         * 
112         * @param accountsPayableDocument
113         * @return
114         */
115        protected boolean validateInvoiceTotalsAreMismatched(AccountsPayableDocument accountsPayableDocument) {
116            boolean mismatched = false;
117            String[] excludeArray = { PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE };
118            if (accountsPayableDocument.getTotalDollarAmountAllItems(excludeArray).compareTo(accountsPayableDocument.getInitialAmount()) != 0 && !accountsPayableDocument.isUnmatchedOverride()) {
119                mismatched = true;
120            }
121    
122            return mismatched;
123        }
124    
125        /**
126         * Exists to be overriden by the child class and return the name of the document.
127         * 
128         * @return
129         */
130        public String getDocumentName() {
131            return "";
132        }
133    
134    }