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.endow.util;
017    
018    import java.math.BigDecimal;
019    
020    /**
021     * This class will ensure Calculation Rounding Rules in KEM: - No calculated value will ever be truncated to the decimals set for
022     * the field. - Every calculation made by the system must always round to the proper decimal for the field. - Each field has a
023     * decimal value and the calculation results carry past the expected decimals and if the next decimal value is greater than or equal
024     * to 5, the last decimal value will be incremented by 1. - If the calculation results carry past the expected decimals and if the
025     * next decimal value is less than 5, the last decimal value will not be incremented.
026     */
027    public class KEMCalculationRoundingHelper {
028    
029        /**
030         * Divides two decimals and applies the given scale and a ROUND_HALF_UP. This method should be used only for the final result
031         * calculation. For example if we have something like this: (axb)/c the rules should be applied to the result of the division
032         * only and not all the computations that give us the final result.
033         * 
034         * @param dividend the dividend
035         * @param divisor the divisor
036         * @param scale the scale for the result
037         * @return the result of the division after the scale and rounding are applied
038         */
039        public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor, int scale) {
040    
041            BigDecimal result = BigDecimal.ZERO;
042    
043            if (dividend != null && divisor != null && !divisor.equals(BigDecimal.ZERO)) {
044                result = dividend.divide(divisor, scale, BigDecimal.ROUND_HALF_UP);
045            }
046    
047            return result;
048        }
049    
050        /**
051         * Multiplies two decimals and applies the given scale and a ROUND_HALF_UP. This method should be used only for the final result
052         * calculation.For example if we have something like this: (axb)/c the rules should be applied to the result of the division
053         * only and not all the computations that give us the final result.
054         * 
055         * @param multiplier1 first multiplier
056         * @param multiplier2 second multiplier
057         * @param scale the scale fo the result
058         * @return the result of the multiplication after scale and rounding are applied
059         */
060        public static BigDecimal multiply(BigDecimal multiplier1, BigDecimal multiplier2, int scale) {
061    
062            BigDecimal result = BigDecimal.ZERO;
063            
064            if (multiplier1 != null && multiplier2 != null) {
065                result = multiplier1.multiply(multiplier2);
066            }
067            
068            result = result.setScale(scale, BigDecimal.ROUND_HALF_UP);
069            return result;
070        }
071    
072    }