Branch data Line data Source code
1 : : /********************************************************************\
2 : : * gnc-euro.c -- utilities for EURO currency *
3 : : * *
4 : : * Copyright (C) 2000 Herbert Thoma *
5 : : * *
6 : : * This program is free software; you can redistribute it and/or *
7 : : * modify it under the terms of the GNU General Public License as *
8 : : * published by the Free Software Foundation; either version 2 of *
9 : : * the License, or (at your option) any later version. *
10 : : * *
11 : : * This program is distributed in the hope that it will be useful, *
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 : : * GNU General Public License for more details. *
15 : : * *
16 : : * You should have received a copy of the GNU General Public License*
17 : : * along with this program; if not, write to the Free Software *
18 : : * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 : : * *
20 : : \********************************************************************/
21 : :
22 : : #include <string>
23 : : #include <boost/container/flat_map.hpp>
24 : : #include <optional>
25 : :
26 : : #include "gnc-euro.h"
27 : : #include "gnc-session.h"
28 : : #include <gnc-numeric.hpp>
29 : : #include <gnc-rational-rounding.hpp>
30 : :
31 : : /* The rates are per EURO and are denoted in GncNumeric */
32 : : static const boost::container::flat_map <std::string, GncNumeric> gnc_euro_rates =
33 : : {
34 : : { "ATS", {137603, 10000} }, /* austrian schilling */
35 : : { "BEF", {403399, 10000} }, /* belgian franc */
36 : : { "BGN", {195583, 100000} }, /* Bulgarian lev */
37 : : { "CYP", {585274, 1000000} }, /* cyprus pound */
38 : : { "DEM", {195583, 100000} }, /* german mark */
39 : : { "EEK", {156466, 10000} }, /* Estonian Kroon */
40 : : { "ESP", {166386, 1000} }, /* spanish peseta */
41 : : { "EUR", { 1, 1} }, /* euro */
42 : : { "FIM", {594573, 100000} }, /* finnmark */
43 : : { "FRF", {655957, 100000} }, /* french franc */
44 : : { "GRD", {340750, 1000} }, /* greek drachma */
45 : : { "HRK", {753450, 100000} }, /* Croatian kuna */
46 : : { "IEP", {787564, 1000000} }, /* irish pound */
47 : : { "ITL", {193627, 100} }, /* italian lira */
48 : : { "LUF", {403399, 10000} }, /* luxembourg franc */
49 : : { "LVL", {702804, 1000000} }, /* latvian lats */
50 : : { "MTL", {429300, 1000000} }, /* maltese lira */
51 : : { "NLG", {220371, 100000} }, /* netherland gulden */
52 : : { "PTE", {200482, 1000} }, /* portuguese escudo */
53 : : { "SIT", {239640, 1000} }, /* slovenian tolar */
54 : : { "SKK", {301260, 10000} } /* slovak koruna */
55 : : };
56 : :
57 : : static std::optional<GncNumeric>
58 : 7476 : get_euro_rate (const gnc_commodity * currency)
59 : : {
60 : 7476 : if (!currency || !gnc_commodity_is_iso(currency))
61 : 0 : return {};
62 : :
63 : 14952 : auto it = gnc_euro_rates.find (gnc_commodity_get_mnemonic(currency));
64 : 7476 : if (it == gnc_euro_rates.end())
65 : 7421 : return {};
66 : :
67 : 55 : return it->second;
68 : : }
69 : :
70 : : /* ------------------------------------------------------ */
71 : :
72 : : gboolean
73 : 7435 : gnc_is_euro_currency(const gnc_commodity * currency)
74 : : {
75 : 7435 : return get_euro_rate (currency).has_value();
76 : : }
77 : :
78 : : /* ------------------------------------------------------ */
79 : :
80 : : gnc_numeric
81 : 11 : gnc_convert_to_euro(const gnc_commodity * currency, gnc_numeric value)
82 : : {
83 : 11 : auto euro_rate = get_euro_rate (currency);
84 : 11 : if (!euro_rate)
85 : 0 : return gnc_numeric_zero();
86 : :
87 : : /* round to 2 decimal places */
88 : : /* EC Regulation 1103/97 states we should use "Round half away from zero"
89 : : * See https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A31997R1103&qid=1662917247821
90 : : */
91 : 11 : return (value / *euro_rate).convert<RoundType::half_up>(100);
92 : : }
93 : :
94 : : /* ------------------------------------------------------ */
95 : :
96 : : gnc_numeric
97 : 10 : gnc_convert_from_euro(const gnc_commodity * currency, gnc_numeric value)
98 : : {
99 : 10 : auto euro_rate = get_euro_rate (currency);
100 : 10 : if (!euro_rate)
101 : 0 : return gnc_numeric_zero();
102 : :
103 : : /* EC Regulation 1103/97 states we should use "Round half away from zero"
104 : : * See http://europa.eu/legislation_summaries/economic_and_monetary_affairs/institutional_and_economic_framework/l25025_en.htm */
105 : 10 : return (value * *euro_rate).convert<RoundType::half_up>(gnc_commodity_get_fraction (currency));
106 : : }
107 : :
108 : : /* ------------------------------------------------------ */
109 : :
110 : : gnc_numeric
111 : 20 : gnc_euro_currency_get_rate (const gnc_commodity *currency)
112 : : {
113 : 20 : auto euro_rate = get_euro_rate (currency);
114 : 20 : if (!euro_rate)
115 : 0 : return gnc_numeric_zero();
116 : :
117 : 20 : return static_cast<gnc_numeric>(*euro_rate);
118 : : }
119 : :
120 : : /* ------------------------------------------------------ */
121 : :
122 : : gnc_commodity *
123 : 0 : gnc_get_euro (void)
124 : : {
125 : 0 : QofBook* book = qof_session_get_book (gnc_get_current_session ());
126 : 0 : gnc_commodity_table *table = gnc_commodity_table_get_table (book);
127 : :
128 : 0 : return gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY, "EUR");
129 : : }
|