/**
* 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.base.service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.axelor.apps.base.db.Currency;
import com.axelor.apps.base.db.CurrencyConversionLine;
import com.axelor.apps.base.exceptions.IExceptionMessage;
import com.axelor.apps.base.service.administration.GeneralService;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.google.inject.Inject;
public class CurrencyService {
private final Logger log = LoggerFactory.getLogger(getClass());
protected GeneralService generalService;
private LocalDate today;
@Inject
public CurrencyService(GeneralService generalService) {
this.generalService = generalService;
this.today = generalService.getTodayDate();
}
public CurrencyService(LocalDate today) {
this.generalService = Beans.get(GeneralService.class);
this.today = today;
}
public BigDecimal getCurrencyConversionRate(Currency startCurrency, Currency endCurrency) throws AxelorException {
CurrencyConversionLine currencyConversionLine = this.getCurrencyConversionLine(startCurrency, endCurrency, today);
if(currencyConversionLine != null) {
return currencyConversionLine.getExchangeRate();
}
else {
currencyConversionLine = this.getCurrencyConversionLine(endCurrency, startCurrency, today);
}
if(currencyConversionLine == null) {
throw new AxelorException(String.format(I18n.get(IExceptionMessage.CURRENCY_1), startCurrency, endCurrency, today), IException.CONFIGURATION_ERROR);
}
return currencyConversionLine.getExchangeRate();
}
private CurrencyConversionLine getCurrencyConversionLine(Currency startCurrency, Currency endCurrency, LocalDate localDate) {
List<CurrencyConversionLine> currencyConversionLineList = generalService.getCurrencyConfigurationLineList();
if(currencyConversionLineList == null) {
return null;
}
log.debug("Currency from: {}, Currency to: {}, localDate: {}", startCurrency, endCurrency, localDate);
for(CurrencyConversionLine ccl : currencyConversionLineList) {
String cclStartCode = ccl.getStartCurrency().getCode();
String cclEndCode = ccl.getEndCurrency().getCode();
String startCode = startCurrency.getCode();
String endCode = endCurrency.getCode();
LocalDate fromDate = ccl.getFromDate();
LocalDate toDate = ccl.getToDate();
if(cclStartCode.equals(startCode) && cclEndCode.equals(endCode)){
if((fromDate.isBefore(localDate) || fromDate.equals(localDate))
&& (toDate == null || toDate.isAfter(localDate) || toDate.isEqual(localDate))) {
return ccl;
}
}
}
return null;
}
public BigDecimal getAmountCurrencyConverted(Currency currencyStart, Currency currencyEnd, BigDecimal amountToPay, LocalDate localDate) throws AxelorException {
// Si la devise source est différente de la devise d'arrivée
// Alors on convertit
if(currencyStart != null && currencyEnd != null && !currencyStart.equals(currencyEnd)) {
// CONVERTIR
CurrencyConversionLine currencyConversionLine = this.getCurrencyConversionLine(currencyStart, currencyEnd, this.getDateToConvert(localDate));
if(currencyConversionLine != null) {
return amountToPay.multiply(currencyConversionLine.getExchangeRate());
}
else {
currencyConversionLine = this.getCurrencyConversionLine(currencyEnd, currencyStart, this.getDateToConvert(localDate));
}
if(currencyConversionLine == null) {
throw new AxelorException(String.format(I18n.get(IExceptionMessage.CURRENCY_1),
currencyStart.getName(), currencyEnd.getName(), today), IException.CONFIGURATION_ERROR);
}
BigDecimal exchangeRate = currencyConversionLine.getExchangeRate();
if(exchangeRate == null || exchangeRate.compareTo(BigDecimal.ZERO) == 0) {
throw new AxelorException(String.format(I18n.get(IExceptionMessage.CURRENCY_2),
currencyStart.getName(), currencyEnd.getName(), today), IException.CONFIGURATION_ERROR);
}
return amountToPay.divide(exchangeRate, generalService.getNbDecimalDigitForUnitPrice(), RoundingMode.HALF_UP);
}
return amountToPay;
}
public LocalDate getDateToConvert(LocalDate date) {
if(date == null) { date = this.today; }
return date;
}
}