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.ld.util;
017    
018    import org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine;
019    import org.kuali.kfs.sys.KFSConstants;
020    import org.kuali.kfs.sys.context.SpringContext;
021    import org.kuali.kfs.sys.document.service.DebitDeterminerService;
022    import org.kuali.rice.kns.util.KualiDecimal;
023    
024    /**
025     * This class provides a set of utilities that handle the debit credit logic.
026     */
027    public class DebitCreditUtil {
028    
029        /**
030         * Determine the Debit Credit code based on the given amount. Normally (isReverse flag is set as false), the debit code returns
031         * if the amount is positive while the credit code returns if the amount is negative. When isReverse flag is set as true, the
032         * credit returns for positive amount and the debit code for negative amount.
033         * 
034         * @param amount the given amount, which can be either negative or positive number.
035         * @param isReversed a flag that indicates if normal accounting practice is used. False for normal accoutning practice; true for
036         *        reverse.
037         * @return the Debit Credit code based on the given transaction amount and the value of isReversed
038         */
039        public static String getDebitCreditCode(KualiDecimal amount, boolean isReversed) {
040            return getDebitCreditCode(amount, "", isReversed);
041        }
042    
043        /**
044         * Determine the Debit Credit code based on the given amount. Normally (isReverse flag is set as false), the debit code returns
045         * if the amount is positive while the credit code returns if the amount is negative. When isReverse flag is set as true, the
046         * credit returns for positive amount and the debit code for negative amount.
047         * 
048         * @param amount the given amount, which can be either negative or positive number.
049         * @param currentDebitCreditCode the current debit credit code
050         * @param isReversed a flag that indicates if normal accounting practice is used. False for normal accoutning practice; true for
051         *        reverse.
052         * @return the Debit Credit code based on the given transaction amount and the value of isReversed
053         */
054        public static String getDebitCreditCode(KualiDecimal amount, String currentDebitCreditCode, boolean isReversed) {
055            String debitCreditCode = null;
056            if (amount.isNegative()) {
057                if (KFSConstants.GL_CREDIT_CODE.equals(currentDebitCreditCode)) {
058                    debitCreditCode = KFSConstants.GL_DEBIT_CODE;
059                }
060                else {
061                    debitCreditCode = KFSConstants.GL_CREDIT_CODE;
062                }
063            }
064            else {
065                if (KFSConstants.GL_CREDIT_CODE.equals(currentDebitCreditCode)) {
066                    debitCreditCode = KFSConstants.GL_CREDIT_CODE;
067                }
068                else {
069                    debitCreditCode = KFSConstants.GL_DEBIT_CODE;
070                }
071            }
072    
073            if (isReversed) {
074                debitCreditCode = getReverseDebitCreditCode(debitCreditCode);
075            }
076            return debitCreditCode;
077        }
078    
079        /**
080         * Determines the Debit Credit code for the expense accountine line (Salary Expense and Benefit Expense documents).
081         * 
082         * @param accountingLine - line to determine code for
083         * @return String representing the debit/credit code for the line
084         */
085        public static String getDebitCreditCodeForExpenseDocument(ExpenseTransferAccountingLine accountingLine) {
086            String debitCreditCode = null;
087            boolean isPositiveAmount = accountingLine.getAmount().isPositive();
088    
089            if (accountingLine.isSourceAccountingLine()) {
090                if (isPositiveAmount) {
091                    debitCreditCode = KFSConstants.GL_CREDIT_CODE;
092                }
093                else {
094                    debitCreditCode = KFSConstants.GL_DEBIT_CODE;
095                }
096            }
097            else if (accountingLine.isTargetAccountingLine()) {
098                if (isPositiveAmount) {
099                    debitCreditCode = KFSConstants.GL_DEBIT_CODE;
100                }
101                else {
102                    debitCreditCode = KFSConstants.GL_CREDIT_CODE;
103                }
104            }
105            else {
106                DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
107                throw new IllegalStateException(isDebitUtils.getInvalidLineTypeIllegalArgumentExceptionMessage());
108            }
109    
110            return debitCreditCode;
111        }
112    
113        /**
114         * get the reversed debit credit code of the given code
115         * 
116         * @param currentDebitCreditCode the current debit credit code
117         * @return the reversed debit credit code of the given code
118         */
119        public static String getReverseDebitCreditCode(String currentDebitCreditCode) {
120            if (KFSConstants.GL_DEBIT_CODE.equals(currentDebitCreditCode)) {
121                return KFSConstants.GL_CREDIT_CODE;
122            }
123    
124            if (KFSConstants.GL_CREDIT_CODE.equals(currentDebitCreditCode)) {
125                return KFSConstants.GL_DEBIT_CODE;
126            }
127    
128            return KFSConstants.GL_CREDIT_CODE;
129        }
130    
131        /**
132         * Determine the actual amount based on Debit Credit code. If the code is credit code, then change the sign of the given amount;
133         * otherwise, do nothing
134         * 
135         * @param amount the given amount, which can be either negative or positive number.
136         * @param currentDebitCreditCode the current debit credit code
137         * @return the actual numeric amount of the given amount
138         */
139        public static KualiDecimal getNumericAmount(KualiDecimal amount, String currentDebitCreditCode) {
140            KualiDecimal actualAmount = amount;
141    
142            if (amount == null) {
143                actualAmount = KualiDecimal.ZERO;
144            }
145            else if (KFSConstants.GL_CREDIT_CODE.equals(currentDebitCreditCode)) {
146                actualAmount = actualAmount.multiply(new KualiDecimal(-1));
147            }
148            return actualAmount;
149        }
150    }