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.fp.document.validation.impl;
017    
018    import static org.kuali.kfs.sys.KFSConstants.AUXILIARY_LINE_HELPER_PROPERTY_NAME;
019    import static org.kuali.kfs.sys.KFSConstants.CREDIT_AMOUNT_PROPERTY_NAME;
020    import static org.kuali.kfs.sys.KFSConstants.DEBIT_AMOUNT_PROPERTY_NAME;
021    import static org.kuali.kfs.sys.KFSConstants.GL_DEBIT_CODE;
022    import static org.kuali.kfs.sys.KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME;
023    import static org.kuali.kfs.sys.KFSConstants.SQUARE_BRACKET_LEFT;
024    import static org.kuali.kfs.sys.KFSConstants.SQUARE_BRACKET_RIGHT;
025    import static org.kuali.kfs.sys.KFSConstants.VOUCHER_LINE_HELPER_CREDIT_PROPERTY_NAME;
026    import static org.kuali.kfs.sys.KFSConstants.VOUCHER_LINE_HELPER_DEBIT_PROPERTY_NAME;
027    import static org.kuali.kfs.sys.KFSKeyConstants.ERROR_ZERO_OR_NEGATIVE_AMOUNT;
028    
029    import org.apache.commons.lang.StringUtils;
030    import org.kuali.kfs.sys.businessobject.AccountingLine;
031    import org.kuali.kfs.sys.document.validation.GenericValidation;
032    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
033    import org.kuali.rice.kns.util.GlobalVariables;
034    import org.kuali.rice.kns.util.KualiDecimal;
035    
036    /**
037     * The Auxiliary Voucher's customization of the accounting line amount validation.
038     */
039    public class AuxiliaryVoucherAccountingLineAmountValidation extends GenericValidation {
040        private AccountingLine accountingLineForValidation;
041    
042        /**
043         * Accounting lines for Auxiliary Vouchers can only be positive non-zero numbers
044         * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
045         */
046        public boolean validate(AttributedDocumentEvent event) {
047            boolean retval = true;
048            KualiDecimal amount = accountingLineForValidation.getAmount();
049    
050            // check for negative or zero amounts
051            if (KualiDecimal.ZERO.equals(amount)) { // if 0
052                GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildErrorMapKeyPathForDebitCreditAmount(true), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
053                GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildErrorMapKeyPathForDebitCreditAmount(false), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
054    
055                retval = false;
056            }
057            else if (amount.isNegative()) { // entered a negative number
058                String debitCreditCode = accountingLineForValidation.getDebitCreditCode();
059                if (StringUtils.isNotBlank(debitCreditCode) && GL_DEBIT_CODE.equals(debitCreditCode)) {
060                    GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildErrorMapKeyPathForDebitCreditAmount(true), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
061                }
062                else {
063                    GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(buildErrorMapKeyPathForDebitCreditAmount(false), ERROR_ZERO_OR_NEGATIVE_AMOUNT, "an accounting line");
064                }
065    
066                retval = false;
067            }
068    
069            return retval;
070        }
071        
072        /**
073         * This method looks at the current full key path that exists in the ErrorMap structure to determine how to build the error map
074         * for the special journal voucher credit and debit fields since they don't conform to the standard pattern of accounting lines.
075         * 
076         * @param isDebit boolean to determine whether or not value isDebit or not
077         * @return String represents error map key to use
078         */
079        protected String buildErrorMapKeyPathForDebitCreditAmount(boolean isDebit) {
080            // determine if we are looking at a new line add or an update
081            boolean isNewLineAdd = GlobalVariables.getMessageMap().getErrorPath().contains(NEW_SOURCE_ACCT_LINE_PROPERTY_NAME);
082            isNewLineAdd |= GlobalVariables.getMessageMap().getErrorPath().contains(NEW_SOURCE_ACCT_LINE_PROPERTY_NAME);
083    
084            if (isNewLineAdd) {
085                if (isDebit) {
086                    return DEBIT_AMOUNT_PROPERTY_NAME;
087                }
088                else {
089                    return CREDIT_AMOUNT_PROPERTY_NAME;
090                }
091            }
092            else {
093                String index = StringUtils.substringBetween(GlobalVariables.getMessageMap().getKeyPath("", true), SQUARE_BRACKET_LEFT, SQUARE_BRACKET_RIGHT);
094                String indexWithParams = SQUARE_BRACKET_LEFT + index + SQUARE_BRACKET_RIGHT;
095                if (isDebit) {
096                    return AUXILIARY_LINE_HELPER_PROPERTY_NAME + indexWithParams + VOUCHER_LINE_HELPER_DEBIT_PROPERTY_NAME;
097                }
098                else {
099                    return AUXILIARY_LINE_HELPER_PROPERTY_NAME + indexWithParams + VOUCHER_LINE_HELPER_CREDIT_PROPERTY_NAME;
100                }
101            }
102        }
103    
104        /**
105         * Gets the accountingLineForValidation attribute. 
106         * @return Returns the accountingLineForValidation.
107         */
108        public AccountingLine getAccountingLineForValidation() {
109            return accountingLineForValidation;
110        }
111    
112        /**
113         * Sets the accountingLineForValidation attribute value.
114         * @param accountingLineForValidation The accountingLineForValidation to set.
115         */
116        public void setAccountingLineForValidation(AccountingLine accountingLineForValidation) {
117            this.accountingLineForValidation = accountingLineForValidation;
118        }
119    }