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 }