blob: ad2c73cfa07fa52efd2e06b5962965419b312b7b [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*/
package org.eclipse.osbp.utils.currency;
import java.math.BigDecimal;
import java.util.Currency;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import org.joda.money.CurrencyUnit;
import org.joda.money.IllegalCurrencyException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/**
* all Euro based reference rates for one currency unit
*/
public final class EuroBasedCurrencyConversionData {
private final CurrencyUnit fCurrencyUnit;
private final Currency fCurrency;
private DateTime fOldestReferenceDate;
private DateTime fNewestReferenceDate;
private final Map<DateTime, BigDecimal> sReferenceRates;
/**
* @param currencyUnit the currency unit, for which the rates are given
*/
protected EuroBasedCurrencyConversionData(CurrencyUnit currencyUnit) {
fCurrencyUnit = currencyUnit;
fCurrency = Currency.getInstance(fCurrencyUnit.getCode());
fOldestReferenceDate = new DateTime(2999, 12, 31, 0, 0);
fNewestReferenceDate = new DateTime(1900, 1, 1, 0, 0);
if (CurrencyUnit.EUR.equals(fCurrencyUnit)) {
sReferenceRates = null;
}
else {
sReferenceRates = new HashMap<DateTime, BigDecimal>();
}
}
/**
* TODO if no rate is given for the date, use the previous date, because of weekends
* TODO if reference date is in the "future", it may be available too, if it the newest reference rate is on friday and the requested reference date is on the following weekend
* @param referenceDate for which the rate is requested
* @return the Euro based reference rate
*/
public BigDecimal getReferenceRate(DateTime referenceDate) {
if (CurrencyUnit.EUR.equals(fCurrencyUnit)) {
// --- for Euro always return 1.0 ---
return BigDecimal.ONE;
}
else if ((fOldestReferenceDate.compareTo(referenceDate) > 0 ) || (fNewestReferenceDate.compareTo(referenceDate) < 0)) {
throw new IllegalCurrencyException("No euro exchange reference rate for currency "+fCurrencyUnit.getCurrencyCode()+" for "+referenceDate+" available, only in ["+fOldestReferenceDate.toString(TO_STRING_DATE_FORMAT)+","+fNewestReferenceDate.toString(TO_STRING_DATE_FORMAT)+"]");
}
else {
DateTime index = Utilities.toIndexingDateTime(referenceDate);
while (!sReferenceRates.containsKey(index)) {
index = index.minusDays(1);
}
return sReferenceRates.get(index);
}
}
/**
* the internal index does only respect year & month & day
* @param referenceDate for which the rate is set
* @param referenceRate the Euro based reference rate
*/
protected void putReferenceRate(DateTime referenceDate, BigDecimal referenceRate) {
DateTime index = new DateTime(referenceDate.getYear(), referenceDate.getMonthOfYear(), referenceDate.getDayOfMonth(), 0, 0);
// --- only for non-Euro save the rates ---
if (!CurrencyUnit.EUR.equals(fCurrencyUnit)) {
sReferenceRates.put(index, referenceRate);
}
if (index.compareTo(fOldestReferenceDate) < 0) {
fOldestReferenceDate = index;
}
if (index.compareTo(fNewestReferenceDate) > 0) {
fNewestReferenceDate = index;
}
}
/**
* @return the currency unit
*/
public CurrencyUnit getCurrencyUnit() {
return fCurrencyUnit;
}
/**
* @return the currency unit
*/
public Currency getCurrency() {
return fCurrency;
}
/**
* @return the oldest available reference date
*/
public DateTime getOldestReferenceDate() {
return fOldestReferenceDate;
}
/**
* TODO if reference date is in the "future", it may be available too, if it the newest reference rate is on friday and the requested reference date is on the following weekend
* @return the newest available reference date
*/
public DateTime getNewestReferenceDate() {
return fNewestReferenceDate;
}
/**
* @return a ISO-3166-1 ordered map with ISO-3166-1 country codes and the corresponding locale
*/
public Map<String,Locale> getCountryMap() {
Map<String,Locale> result = new TreeMap<String,Locale>();
for (String country : fCurrencyUnit.getCountryCodes()) {
result.put(country, new Locale("", country));
}
return result;
}
private static DateTimeFormatter TO_STRING_DATE_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd/EE");
public String toString() {
String retcode = fCurrencyUnit.getCode()+" / "+fCurrencyUnit.getDefaultFractionDigits()+" ["+fOldestReferenceDate.toString(TO_STRING_DATE_FORMAT)+" - "+fNewestReferenceDate.toString(TO_STRING_DATE_FORMAT)+"] = "+fCurrencyUnit.getSymbol()+" = "+fCurrency.getDisplayName()+ " / "+fCurrencyUnit.getCountryCodes().size()+" countries /";
Map<String, Locale> countries = getCountryMap();
for (String country : countries.keySet()) {
retcode += " ("+country+")"+countries.get(country).getDisplayCountry();
}
return retcode;
}
}