/**
* Axelor Business Solutions
*
* Copyright (C) 2016 Axelor (<http://axelor.com>).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.axelor.apps.tool;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.apps.tool.date.DateTool;
/**
* Outils simplifiant l'utilisation des nombres.
*
*/
public final class DecimalTool {
private static final Logger LOG = LoggerFactory.getLogger(DecimalTool.class);
/**
* Proratiser une valeur en fonction de date.
*
* @param fromDate
* Date de début de la période de conso.
* @param toDate
* Date de fin de la période de conso.
* @param date
* Date de proratisation.
* @param value
* Valeur initiale.
*
* @return
* La quantité proratisée.
*/
public static BigDecimal prorata(LocalDate fromDate, LocalDate toDate, LocalDate date, BigDecimal value, int scale){
BigDecimal prorataValue = BigDecimal.ZERO;
if (fromDate == null || toDate == null || date == null) { return prorataValue; }
BigDecimal totalDays = new BigDecimal(DateTool.daysBetween(fromDate, toDate, false));
BigDecimal days = new BigDecimal(DateTool.daysBetween(date, toDate, false));
prorataValue = prorata(totalDays, days, value, scale);
LOG.debug("Proratisation ({} pour {} à {}) à la date du {} : {}", new Object[] {value, fromDate, toDate, date, prorataValue});
return prorataValue;
}
/**
* Proratiser une valeur en fonction du nombre de jours. (Règle de 3)
*
* @param totalDays
* Le nombre total de jour.
* @param days
* Le nombre de jour.
* @param value
* La valeur à proratiser.
*
* @return
* La valeur proratisée.
*/
public static BigDecimal prorata(BigDecimal totalDays, BigDecimal days, BigDecimal value, int scale) {
BigDecimal prorataValue = BigDecimal.ZERO;
if (totalDays.compareTo(prorataValue) == 0) {
return prorataValue;
}
else {
prorataValue = (days.multiply(value).divide(totalDays, scale, BigDecimal.ROUND_HALF_EVEN)).setScale(scale, RoundingMode.HALF_EVEN);
}
LOG.debug("Proratisation d'une valeur sur un total de jour {} pour {} jours et une valeur de {} : {}", new Object[] { totalDays, days, value, prorataValue });
return prorataValue;
}
public static BigDecimal prorata(LocalDate fromDate, LocalDate toDate, LocalDate date, BigDecimal value){
return prorata(fromDate, toDate, date, value, 2);
}
public static BigDecimal prorata(BigDecimal totalDays, BigDecimal days, BigDecimal value) {
return prorata(totalDays, days, value, 2);
}
/**
* Fonction permettant d'obtenir le pourcentage d'une valeur.
*
* @param value
* Valeur initiale.
* @param percent
* Pourcentage (format : 10%).
* @param scale
* Précision.
*
* @return
* Le pourcentage de la valeur initiale.
*/
public static BigDecimal percent(BigDecimal value, BigDecimal percent, int scale){
return value.multiply(percent).divide(new BigDecimal("100"), scale, RoundingMode.HALF_EVEN);
}
}