GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-euro.c
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 "config.h"
23 
24 #include "gnc-euro.h"
25 
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "app-utils/gnc-ui-util.h"
31 
32 /* local structs */
33 typedef struct
34 {
35  const char *currency;
36  double rate;
38 
39 
40 /* This array MUST be sorted ! */
41 /* The rates are per EURO */
42 static gnc_euro_rate_struct gnc_euro_rates[] =
43 {
44  { "ATS", 13.7603 }, /* austrian schilling */
45  { "BEF", 40.3399 }, /* belgian franc */
46  { "BFR", 40.3399 }, /* belgian franc */
47  { "CYP", .585274 }, /* cyprus pound */
48  { "DEM", 1.95583 }, /* german mark */
49  { "DM", 1.95583 }, /* german mark */
50  { "EEK", 15.6466 }, /* Estonian Kroon */
51  { "ESC", 200.482 }, /* portugese escudo */
52  { "ESP", 166.386 }, /* spanish peseta */
53  { "EUR", 1.00000 }, /* euro */
54  { "EURO", 1.00000 }, /* euro */
55  { "FF", 6.55957 }, /* french franc */
56  { "FIM", 5.94573 }, /* finnmark */
57  { "FMK", 5.94573 }, /* finnmark */
58  { "FRF", 6.55957 }, /* french franc */
59  { "GRD", 340.750 }, /* greek drachma */
60  { "HFL", 2.20371 }, /* netherland gulden */
61  { "IEP", .787564 }, /* irish pound */
62  { "IRP", .787564 }, /* irish pound */
63  { "ITL", 1936.27 }, /* italian lira */
64  { "LFR", 40.3399 }, /* luxembourg franc */
65  { "LIT", 1936.27 }, /* italian lira */
66  { "LUF", 40.3399 }, /* luxembourg franc */
67  { "LVL", .702804 }, /* latvian lats */
68  { "MTL", .429300 }, /* maltese lira */
69  { "NLG", 2.20371 }, /* netherland gulden */
70  { "PTA", 166.386 }, /* spanish peseta */
71  { "PTE", 200.482 }, /* portugese escudo */
72  { "S", 13.7603 }, /* austrian schilling */
73  { "SCH", 13.7603 }, /* austrian schilling */
74  { "SIT", 239.640 }, /* slovenian tolar */
75  { "SKK", 30.1260 } /* slovak koruna */
76 };
77 
78 static int
79 gnc_euro_rate_compare (const void * key, const void * value)
80 {
81  const gnc_commodity * curr = key;
82  const gnc_euro_rate_struct * euro = value;
83 
84  if (!key || !value)
85  return -1;
86 
87  return g_ascii_strcasecmp(gnc_commodity_get_mnemonic(curr), euro->currency);
88 }
89 
90 #if 0 /* Not Used */
91 static int
92 gnc_euro_rate_compare_code (const void * key, const void * value)
93 {
94  const char *code = key;
95  const gnc_euro_rate_struct * euro = value;
96 
97  if (!key || !value)
98  return -1;
99 
100  return g_ascii_strcasecmp (code, euro->currency);
101 }
102 #endif
103 
104 /* ------------------------------------------------------ */
105 
106 gboolean
107 gnc_is_euro_currency(const gnc_commodity * currency)
108 {
109  gnc_euro_rate_struct *result;
110 
111  if (currency == NULL)
112  return FALSE;
113 
114  if (!gnc_commodity_is_iso(currency))
115  return FALSE;
116 
117  result = bsearch(currency,
118  gnc_euro_rates,
119  sizeof(gnc_euro_rates) / sizeof(gnc_euro_rate_struct),
120  sizeof(gnc_euro_rate_struct),
121  gnc_euro_rate_compare);
122 
123  if (result == NULL)
124  return FALSE;
125 
126  return TRUE;
127 }
128 
129 /* ------------------------------------------------------ */
130 
132 gnc_convert_to_euro(const gnc_commodity * currency, gnc_numeric value)
133 {
134  gnc_euro_rate_struct *result;
135 
136  if (currency == NULL)
137  return gnc_numeric_zero ();
138 
139  if (!gnc_commodity_is_iso(currency))
140  return gnc_numeric_zero ();
141 
142  result = bsearch(currency,
143  gnc_euro_rates,
144  sizeof(gnc_euro_rates) / sizeof(gnc_euro_rate_struct),
145  sizeof(gnc_euro_rate_struct),
146  gnc_euro_rate_compare);
147 
148  if (result == NULL)
149  return gnc_numeric_zero ();
150 
151  /* round to 2 decimal places */
152  {
153  gnc_numeric rate;
154 
155  rate = double_to_gnc_numeric (result->rate, 100000, GNC_HOW_RND_ROUND_HALF_UP);
156 
157  /* EC Regulation 1103/97 states we should use "Round half away from zero"
158  * See http://europa.eu/legislation_summaries/economic_and_monetary_affairs/institutional_and_economic_framework/l25025_en.htm */
159  return gnc_numeric_div (value, rate, 100, GNC_HOW_RND_ROUND_HALF_UP);
160  }
161 }
162 
163 /* ------------------------------------------------------ */
164 
166 gnc_convert_from_euro(const gnc_commodity * currency, gnc_numeric value)
167 {
168  gnc_euro_rate_struct * result;
169 
170  if (currency == NULL)
171  return gnc_numeric_zero ();
172 
173  if (!gnc_commodity_is_iso(currency))
174  return gnc_numeric_zero ();
175 
176  result = bsearch(currency,
177  gnc_euro_rates,
178  sizeof(gnc_euro_rates) / sizeof(gnc_euro_rate_struct),
179  sizeof(gnc_euro_rate_struct),
180  gnc_euro_rate_compare);
181 
182  if (result == NULL)
183  return gnc_numeric_zero ();
184 
185  {
186  gnc_numeric rate;
187 
188  rate = double_to_gnc_numeric (result->rate, 100000, GNC_HOW_RND_ROUND_HALF_UP);
189 
190  /* EC Regulation 1103/97 states we should use "Round half away from zero"
191  * See http://europa.eu/legislation_summaries/economic_and_monetary_affairs/institutional_and_economic_framework/l25025_en.htm */
192  return gnc_numeric_mul (value, rate, gnc_commodity_get_fraction (currency),
194  }
195 }
196 
197 /* ------------------------------------------------------ */
198 
200 gnc_euro_currency_get_rate (const gnc_commodity *currency)
201 {
202  gnc_euro_rate_struct * result;
203 
204  if (currency == NULL)
205  return gnc_numeric_zero ();
206 
207  if (!gnc_commodity_is_iso(currency))
208  return gnc_numeric_zero ();
209 
210  result = bsearch(currency,
211  gnc_euro_rates,
212  sizeof(gnc_euro_rates) / sizeof(gnc_euro_rate_struct),
213  sizeof(gnc_euro_rate_struct),
214  gnc_euro_rate_compare);
215 
216  if (result == NULL)
217  return gnc_numeric_zero ();
218 
219  return double_to_gnc_numeric (result->rate, GNC_DENOM_AUTO,
221 }
222 
223 /* ------------------------------------------------------ */
224 
226 gnc_get_euro (void)
227 {
229 
230  table = gnc_commodity_table_get_table (gnc_get_current_book ());
231 
232  return gnc_commodity_table_lookup (table, GNC_COMMODITY_NS_CURRENCY, "EUR");
233 }
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
int gnc_commodity_get_fraction(const gnc_commodity *cm)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
utility functions for the GnuCash UI
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246
#define GNC_HOW_DENOM_SIGFIGS(n)
Definition: gnc-numeric.h:218
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)