gpe-expenses  0.1.9
qof-expenses.c
1 /***************************************************************************
2  * qof-expenses.c
3  *
4  * Thu Oct 21 07:59:13 2004-2005
5  * Copyright 2004-2009 Neil Williams <linux@codehelp.co.uk>
6  ****************************************************************************/
7 /*
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "config.h"
23 #include <stdlib.h>
24 #include <glib.h>
25 #include <libintl.h>
26 #include <glib/gprintf.h>
27 #include <qof.h>
28 #include <locale.h>
29 #include "qof-expenses.h"
30 #define _(String) dgettext (LIBRARY_GETTEXT_PACKAGE, String)
31 
32 static QofLogModule log_module = GPE_MOD_EXP;
33 
34 AS_STRING_FUNC (ExpenseDistance, DISTANCE_LIST)
35 FROM_STRING_FUNC(ExpenseDistance, DISTANCE_LIST)
36 AS_STRING_FUNC (ExpensePayment, PAYMENT_TYPE_LIST)
37 FROM_STRING_FUNC(ExpensePayment, PAYMENT_TYPE_LIST)
38 /* leave the macro in place to support types.
39  allow translation by mapping the gcc -E output.
40 */
41 AS_STRING_FUNC (ExpenseType, EXPENSE_TYPE_LIST)
42 FROM_STRING_FUNC(ExpenseType, EXPENSE_TYPE_LIST)
43 
48 static GHashTable *qof_currency_table = NULL;
49 
50 void
51 qof_currency_foreach(QofCurrencyCB cb, gpointer user_data)
52 {
53  g_hash_table_foreach(qof_currency_table, cb, user_data);
54 }
55 
72 static void
73 populate_currencies (void)
74 {
75  qof_currency_table = g_hash_table_new(g_direct_hash, g_direct_equal);
76  { /* Australia 0 100 AU$ AUD */
77  QofCurrency *c = g_new0(QofCurrency, 1);
78  c->pq_code = 0;
79  c->fraction = 100;
80  c->symbol = "AU$";
81  c->mnemonic = "AUD";
82  c->non_utf8 = FALSE;
83  g_hash_table_insert(qof_currency_table,
84  GINT_TO_POINTER(c->pq_code), (gpointer)c);
85  }
86  { /* Austria 1 100 € ATS */
87  QofCurrency *c = g_new0(QofCurrency, 1);
88  c->pq_code = 1;
89  c->fraction = 100;
90  c->symbol = "€";
91  c->mnemonic = "ATS";
92  c->non_utf8 = TRUE;
93  g_hash_table_insert(qof_currency_table,
94  GINT_TO_POINTER(c->pq_code), (gpointer)c);
95  }
96  { /* Belgium 2 100 € BEF */
97  QofCurrency *c = g_new0(QofCurrency, 1);
98  c->pq_code = 2;
99  c->fraction = 100;
100  c->symbol = "€";
101  c->mnemonic = "BEF";
102  c->non_utf8 = TRUE;
103  g_hash_table_insert(qof_currency_table,
104  GINT_TO_POINTER(c->pq_code), (gpointer)c);
105  }
106  { /* Brazil 3 100 R$ BRL */
107  QofCurrency *c = g_new0(QofCurrency, 1);
108  c->pq_code = 3;
109  c->fraction = 100;
110  c->symbol = "R$";
111  c->mnemonic = "BRL";
112  c->non_utf8 = FALSE;
113  g_hash_table_insert(qof_currency_table,
114  GINT_TO_POINTER(c->pq_code), (gpointer)c);
115  }
116  { /* Canada 4 100 $CN CAD */
117  QofCurrency *c = g_new0(QofCurrency, 1);
118  c->pq_code = 4;
119  c->fraction = 100;
120  c->symbol = "$CN";
121  c->mnemonic = "CAD";
122  c->non_utf8 = FALSE;
123  g_hash_table_insert(qof_currency_table,
124  GINT_TO_POINTER(c->pq_code), (gpointer)c);
125  }
126  { /* Denmark 5 100 DKK DKK */
127  QofCurrency *c = g_new0(QofCurrency, 1);
128  c->pq_code = 5;
129  c->fraction = 100;
130  c->symbol = "DKK";
131  c->mnemonic = "DKK";
132  c->non_utf8 = FALSE;
133  g_hash_table_insert(qof_currency_table,
134  GINT_TO_POINTER(c->pq_code), (gpointer)c);
135  }
136  { /* Finland 6 100 € FIM */
137  QofCurrency *c = g_new0(QofCurrency, 1);
138  c->pq_code = 6;
139  c->fraction = 100;
140  c->symbol = "€";
141  c->mnemonic = "FIM";
142  c->non_utf8 = TRUE;
143  g_hash_table_insert(qof_currency_table,
144  GINT_TO_POINTER(c->pq_code), (gpointer)c);
145  }
146  { /* France 7 100 € FRF */
147  QofCurrency *c = g_new0(QofCurrency, 1);
148  c->pq_code = 7;
149  c->fraction = 100;
150  c->symbol = "€";
151  c->mnemonic = "FRF";
152  c->non_utf8 = TRUE;
153  g_hash_table_insert(qof_currency_table,
154  GINT_TO_POINTER(c->pq_code), (gpointer)c);
155  }
156  { /* Germany 8 100 € DEM */
157  QofCurrency *c = g_new0(QofCurrency, 1);
158  c->pq_code = 8;
159  c->fraction = 100;
160  c->symbol = "€";
161  c->mnemonic = "DEM";
162  c->non_utf8 = TRUE;
163  g_hash_table_insert(qof_currency_table,
164  GINT_TO_POINTER(c->pq_code), (gpointer)c);
165  }
166  { /* Hong Kong 9 100 HK$ HKD */
167  QofCurrency *c = g_new0(QofCurrency, 1);
168  c->pq_code = 9;
169  c->fraction = 100;
170  c->symbol = "HK$";
171  c->mnemonic = "HKD";
172  c->non_utf8 = FALSE;
173  g_hash_table_insert(qof_currency_table,
174  GINT_TO_POINTER(c->pq_code), (gpointer)c);
175  }
176  { /* Iceland 10 100 ISK ISK */
177  QofCurrency *c = g_new0(QofCurrency, 1);
178  c->pq_code = 10;
179  c->fraction = 100;
180  c->symbol = "ISK";
181  c->mnemonic = "ISK";
182  c->non_utf8 = FALSE;
183  g_hash_table_insert(qof_currency_table,
184  GINT_TO_POINTER(c->pq_code), (gpointer)c);
185  }
186  { /* Ireland 11 100 € IEP */
187  QofCurrency *c = g_new0(QofCurrency, 1);
188  c->pq_code = 11;
189  c->fraction = 100;
190  c->symbol = "€";
191  c->mnemonic = "IEP";
192  c->non_utf8 = TRUE;
193  g_hash_table_insert(qof_currency_table,
194  GINT_TO_POINTER(c->pq_code), (gpointer)c);
195  }
196  { /* Italy 12 1 EUR ITL */
197  /* The Italian Lira had a fraction == 1*/
198  QofCurrency *c = g_new0(QofCurrency, 1);
199  c->pq_code = 12;
200  c->fraction = 100;
201  c->symbol = "EUR";
202  c->mnemonic = "ITL";
203  c->non_utf8 = FALSE;
204  g_hash_table_insert(qof_currency_table,
205  GINT_TO_POINTER(c->pq_code), (gpointer)c);
206  }
207  { /* Japan 13 1 &#165; ¥ JPY */
208  QofCurrency *c = g_new0(QofCurrency, 1);
209  c->pq_code = 13;
210  c->fraction = 1;
211  c->symbol = "¥";
212  c->mnemonic = "JPY";
213  c->non_utf8 = TRUE;
214  g_hash_table_insert(qof_currency_table,
215  GINT_TO_POINTER(c->pq_code), (gpointer)c);
216  }
217  { /* Luxembourg 14 100 &#136; € LUF */
218  QofCurrency *c = g_new0(QofCurrency, 1);
219  c->pq_code = 14;
220  c->fraction = 100;
221  c->symbol = "€";
222  c->mnemonic = "LUF";
223  c->non_utf8 = TRUE;
224  g_hash_table_insert(qof_currency_table,
225  GINT_TO_POINTER(c->pq_code), (gpointer)c);
226  }
227  { /* Mexico 15 100 MXP MXP */
228  QofCurrency *c = g_new0(QofCurrency, 1);
229  c->pq_code = 15;
230  c->fraction = 100;
231  c->symbol = "MXP";
232  c->mnemonic = "MXP";
233  c->non_utf8 = FALSE;
234  g_hash_table_insert(qof_currency_table,
235  GINT_TO_POINTER(c->pq_code), (gpointer)c);
236  }
237  { /* Netherlands 16 100 € ANG */
238  QofCurrency *c = g_new0(QofCurrency, 1);
239  c->pq_code = 16;
240  c->fraction = 100;
241  c->symbol = "€";
242  c->mnemonic = "ANG";
243  c->non_utf8 = TRUE;
244  g_hash_table_insert(qof_currency_table,
245  GINT_TO_POINTER(c->pq_code), (gpointer)c);
246  }
247  { /* New Zealand 17 100 $NZ NZD */
248  QofCurrency *c = g_new0(QofCurrency, 1);
249  c->pq_code = 17;
250  c->fraction = 100;
251  c->symbol = "$NZ";
252  c->mnemonic = "NZD";
253  c->non_utf8 = FALSE;
254  g_hash_table_insert(qof_currency_table,
255  GINT_TO_POINTER(c->pq_code), (gpointer)c);
256  }
257  { /* Norway 18 100 NOK NOK */
258  QofCurrency *c = g_new0(QofCurrency, 1);
259  c->pq_code = 18;
260  c->fraction = 100;
261  c->symbol = "NOK";
262  c->mnemonic = "NOK";
263  c->non_utf8 = FALSE;
264  g_hash_table_insert(qof_currency_table,
265  GINT_TO_POINTER(c->pq_code), (gpointer)c);
266  }
267  { /* Spain 19 100 € ESP */
268  QofCurrency *c = g_new0(QofCurrency, 1);
269  c->pq_code = 19;
270  c->fraction = 100;
271  c->symbol = "€";
272  c->mnemonic = "ESP";
273  c->non_utf8 = TRUE;
274  g_hash_table_insert(qof_currency_table,
275  GINT_TO_POINTER(c->pq_code), (gpointer)c);
276  }
277  { /* Sweden 20 100 SEK SEK */
278  QofCurrency *c = g_new0(QofCurrency, 1);
279  c->pq_code = 20;
280  c->fraction = 100;
281  c->symbol = "SEK";
282  c->mnemonic = "SEK";
283  c->non_utf8 = FALSE;
284  g_hash_table_insert(qof_currency_table,
285  GINT_TO_POINTER(c->pq_code), (gpointer)c);
286  }
287  { /* Switzerland 21 100 CHF CHF */
288  QofCurrency *c = g_new0(QofCurrency, 1);
289  c->pq_code = 21;
290  c->fraction = 100;
291  c->symbol = "CHF";
292  c->mnemonic = "CHF";
293  c->non_utf8 = FALSE;
294  g_hash_table_insert(qof_currency_table,
295  GINT_TO_POINTER(c->pq_code), (gpointer)c);
296  }
297  { /* United Kingdom 22 100 £ GBP */
298  QofCurrency *c = g_new0(QofCurrency, 1);
299  c->pq_code = 22;
300  c->fraction = 100;
301  c->symbol = "£";
302  c->mnemonic = "GBP";
303  c->non_utf8 = TRUE;
304  g_hash_table_insert(qof_currency_table,
305  GINT_TO_POINTER(c->pq_code), (gpointer)c);
306  }
307  { /* United States 23 100 $US USD */
308  QofCurrency *c = g_new0(QofCurrency, 1);
309  c->pq_code = 23;
310  c->fraction = 100;
311  c->symbol = "$US";
312  c->mnemonic = "USD";
313  c->non_utf8 = FALSE;
314  g_hash_table_insert(qof_currency_table,
315  GINT_TO_POINTER(c->pq_code), (gpointer)c);
316  }
317  { /* India 24 100 Rs INR */
318  QofCurrency *c = g_new0(QofCurrency, 1);
319  c->pq_code = 24;
320  c->fraction = 100;
321  c->symbol = "Rs";
322  c->mnemonic = "INR";
323  c->non_utf8 = FALSE;
324  g_hash_table_insert(qof_currency_table,
325  GINT_TO_POINTER(c->pq_code), (gpointer)c);
326  }
327  { /* Indonesia 25 1 Rp IDR */
328  QofCurrency *c = g_new0(QofCurrency, 1);
329  c->pq_code = 25;
330  c->fraction = 1;
331  c->symbol = "Rp";
332  c->mnemonic = "IDR";
333  c->non_utf8 = FALSE;
334  g_hash_table_insert(qof_currency_table,
335  GINT_TO_POINTER(c->pq_code), (gpointer)c);
336  }
337  { /* Korea 26 100 KRW KRW (South) */
338  QofCurrency *c = g_new0(QofCurrency, 1);
339  c->pq_code = 26;
340  c->fraction = 100;
341  c->symbol = "KRW";
342  c->mnemonic = "KRW";
343  c->non_utf8 = FALSE;
344  g_hash_table_insert(qof_currency_table,
345  GINT_TO_POINTER(c->pq_code), (gpointer)c);
346  }
347  { /* Malaysia 27 100 RM MYR */
348  QofCurrency *c = g_new0(QofCurrency, 1);
349  c->pq_code = 27;
350  c->fraction = 100;
351  c->symbol = "RM";
352  c->mnemonic = "MYR";
353  c->non_utf8 = FALSE;
354  g_hash_table_insert(qof_currency_table,
355  GINT_TO_POINTER(c->pq_code), (gpointer)c);
356  }
357  { /* P.R.C. // People's Rep. China 28 100 RMB CNY */
358  QofCurrency *c = g_new0(QofCurrency, 1);
359  c->pq_code = 28;
360  c->fraction = 100;
361  c->symbol = "RMB";
362  c->mnemonic = "CNY";
363  c->non_utf8 = FALSE;
364  g_hash_table_insert(qof_currency_table,
365  GINT_TO_POINTER(c->pq_code), (gpointer)c);
366  }
367  { /* Phillipines 29 100 P PHP */
368  QofCurrency *c = g_new0(QofCurrency, 1);
369  c->pq_code = 29;
370  c->fraction = 100;
371  c->symbol = "P";
372  c->mnemonic = "PHP";
373  c->non_utf8 = FALSE;
374  g_hash_table_insert(qof_currency_table,
375  GINT_TO_POINTER(c->pq_code), (gpointer)c);
376  }
377  { /* Singapore 30 100 $ SGD */
378  QofCurrency *c = g_new0(QofCurrency, 1);
379  c->pq_code = 30;
380  c->fraction = 100;
381  c->symbol = "$";
382  c->mnemonic = "SGD";
383  c->non_utf8 = FALSE;
384  g_hash_table_insert(qof_currency_table,
385  GINT_TO_POINTER(c->pq_code), (gpointer)c);
386  }
387  { /* Thailand 31 100 BHT THB */
388  QofCurrency *c = g_new0(QofCurrency, 1);
389  c->pq_code = 31;
390  c->fraction = 100;
391  c->symbol = "BHT";
392  c->mnemonic = "THB";
393  c->non_utf8 = FALSE;
394  g_hash_table_insert(qof_currency_table,
395  GINT_TO_POINTER(c->pq_code), (gpointer)c);
396  }
397  { /* Taiwan 32 100 NT$ TWD */
398  QofCurrency *c = g_new0(QofCurrency, 1);
399  c->pq_code = 32;
400  c->fraction = 100;
401  c->symbol = "NT$";
402  c->mnemonic = "TWD";
403  c->non_utf8 = FALSE;
404  g_hash_table_insert(qof_currency_table,
405  GINT_TO_POINTER(c->pq_code), (gpointer)c);
406  }
407  { /* EU (Euro) 133 100 € EUR */
408  QofCurrency *c = g_new0(QofCurrency, 1);
409  c->pq_code = 133;
410  c->fraction = 100;
411  c->symbol = "€";
412  c->mnemonic = "EUR";
413  c->non_utf8 = TRUE;
414  g_hash_table_insert(qof_currency_table,
415  GINT_TO_POINTER(c->pq_code), (gpointer)c);
416  }
417 }
418 
419 static gboolean
420 check_name (gpointer G_GNUC_UNUSED key, gpointer value, gpointer data)
421 {
422  gchar * mnemonic = (gchar*) data;
423  QofCurrency * currency = (QofCurrency*) value;
424  if (0 == safe_strcmp (mnemonic, currency->mnemonic))
425  return TRUE;
426  return FALSE;
427 }
428 
430 qof_currency_lookup_name (QofInstance * inst, gchar * mnemonic)
431 {
432  QofCurrency *currency;
433 
434  currency = NULL;
435  if(!qof_currency_table) populate_currencies();
436  currency = (QofCurrency*) g_hash_table_find
437  (qof_currency_table, check_name, mnemonic);
438  if (!currency) return NULL;
439  qof_currency_lookup(inst, currency->pq_code);
440  return currency;
441 }
442 
444 qof_currency_lookup (QofInstance* inst, gint currency_code)
445 {
446  QofCurrency *currency;
447 
448  currency = NULL;
449  if(!qof_currency_table) populate_currencies();
450  currency = (QofCurrency*)g_hash_table_lookup(
451  qof_currency_table, GINT_TO_POINTER(currency_code));
452  if(!currency)
453  {
454  PERR (" unsupported currency! %d", currency_code);
455  return NULL;
456  }
457  kvp_frame_set_string(qof_instance_get_slots(inst),
458  PQ_CURRENCY_MNEMONIC, currency->mnemonic);
459  kvp_frame_set_gint64(qof_instance_get_slots(inst),
460  PQ_CURRENCY_FRACTION, currency->fraction);
461  if(currency->non_utf8)
462  {
463  gchar * k_symbol = g_strdup (currency->symbol);
464  kvp_frame_set_string(qof_instance_get_slots(inst),
465  PQ_CURRENCY_SYMBOL, qof_util_make_utf8(k_symbol));
466  }
467  else
468  {
469  kvp_frame_set_string(qof_instance_get_slots(inst),
470  PQ_CURRENCY_SYMBOL, currency->symbol);
471  }
472  return currency;
473 }
474 
475 struct QofExp_s
476 {
477  QofInstance inst;
478  ExpenseDistance distance_unit;
479  struct tm date;
480  ExpenseType type;
481  ExpensePayment payment;
482  gint currency_code;
483  gchar *amount;
484  gchar *vendor;
485  gchar *city;
486  gchar *attendees;
487  gchar *note;
488  gchar *category;
489  const gchar* print_string;
490  QofCurrency *currency;
491  gdouble temp_amount;
494  gboolean reset_amount;
495 };
496 
497 static QofExp *
498 expense_create (QofBook *book)
499 {
500  QofExp *obj;
501  QofCollection *coll;
502  GList *all;
503  glong nanosecs;
504  QofTime *qt;
505  QofDate *qd;
506 
507  obj = g_new0(QofExp, 1);
508  qof_instance_init (&obj->inst, GPE_QOF_EXPENSES, book);
509  coll = qof_book_get_collection (book, GPE_QOF_EXPENSES);
510  all = qof_collection_get_data (coll);
511  all = g_list_prepend (all, obj);
512  qof_collection_set_data (coll, all);
513  qt = qof_time_get_current ();
514  nanosecs = qof_time_get_nanosecs (qt);
515  qd = qof_date_from_qtime (qt);
516  if (!qof_date_to_struct_tm (qd, &obj->date, &nanosecs))
517  DEBUG (" failed to set initial date");
518  qof_date_free (qd);
519  qof_time_free (qt);
520  obj->amount = "0";
521  /* 0 == AU$ so use an init value */
522  obj->currency_code = -1;
523  if(!qof_currency_table) populate_currencies();
524  qof_event_gen ((QofEntity*)obj, QOF_EVENT_CREATE, NULL);
525  return obj;
526 }
527 
528 static const gchar*
529 qof_exp_paymentAsString(ExpensePayment payment)
530 {
531  const gchar *string;
532 
533  string = "Cash"; // following install-expenses convention.
534  string = ExpensePaymentasString(payment);
535  return string;
536 }
537 
538 static const gchar*
539 qof_exp_typeAsString(ExpenseType type)
540 {
541  const gchar* string;
542 
543  string = "Bus"; // following install-expenses convention.
544  string = ExpenseTypeasString(type);
545  return string;
546 }
547 
548 static ExpensePayment
549 qof_exp_paymentFromString(const gchar* payment_string)
550 {
551  return ExpensePaymentfromString(payment_string);
552 }
553 
554 static ExpenseType
555 qof_exp_typeFromString(const gchar* type_string)
556 {
557  return ExpenseTypefromString(type_string);
558 }
559 
560 static QofTime *
561 exp_getTime (QofExp * e)
562 {
563  QofDate *qd;
564  QofTime *qt;
565 
566  g_return_val_if_fail (e != NULL, NULL);
567  qd = qof_date_from_struct_tm (&e->date);
568  qt = qof_date_to_qtime (qd);
569  qof_date_free (qd);
570  return qt;
571 }
572 
573 static gchar*
574 exp_getType (QofExp * e)
575 {
576  gchar* string;
577 
578  g_return_val_if_fail (e != NULL, NULL);
579  string = g_strdup(qof_exp_typeAsString(e->type));
580  return string;
581 }
582 
583 static gchar*
584 exp_getPayment (QofExp * e)
585 {
586  gchar* string;
587 
588  g_return_val_if_fail (e != NULL, NULL);
589  string = g_strdup(qof_exp_paymentAsString(e->payment));
590  return string;
591 }
592 
593 static gint
594 exp_getCurrency (QofExp * e)
595 {
596  g_return_val_if_fail (e != NULL, -1);
597  return e->currency_code;
598 }
599 
600 static QofNumeric
601 exp_getAmount (QofExp * e)
602 {
603  QofNumeric amount;
604  gdouble pi_amount;
605  gchar *numeric_char;
606 
607  amount = qof_numeric_zero ();
608  g_return_val_if_fail (e != NULL, amount);
609  if(e->amount == 0) { return amount; }
610  /* floating point as a string converts to gnc_numeric */
611  pi_amount = strtod (e->amount, NULL);
612  if(e->currency)
613  {
614  amount = qof_numeric_from_double (pi_amount, e->currency->fraction,
615  QOF_HOW_DENOM_EXACT | QOF_HOW_RND_ROUND);
616  }
617  else /* default: use the most common fraction in the Palm currency list. */
618  {
619  amount = qof_numeric_from_double (pi_amount, 100,
620  QOF_HOW_DENOM_EXACT | QOF_HOW_RND_ROUND);
621  }
622  numeric_char = qof_numeric_to_string(amount);
623  g_free(numeric_char);
624 
625  if (qof_numeric_check (amount) == QOF_ERROR_OK)
626  return amount;
627  return qof_numeric_zero ();
628 }
629 
630 static const gchar *
631 exp_getVendor (QofExp * e)
632 {
633  g_return_val_if_fail (e != NULL, NULL);
634  return e->vendor;
635 }
636 
637 static const gchar *
638 exp_getCity (QofExp * e)
639 {
640  g_return_val_if_fail (e != NULL, NULL);
641  return e->city;
642 }
643 
644 static const gchar *
645 exp_getAttendees (QofExp * e)
646 {
647  g_return_val_if_fail (e != NULL, NULL);
648  return e->attendees;
649 }
650 
651 static const gchar *
652 exp_getNote (QofExp * e)
653 {
654  g_return_val_if_fail (e != NULL, NULL);
655  return e->note;
656 }
657 
658 static const gchar*
659 exp_getDistance(QofExp *e)
660 {
661  g_return_val_if_fail(e != NULL, NULL);
662  return ExpenseDistanceasString(e->distance_unit);
663 }
664 
665 static const gchar*
666 exp_getCategory(QofExp *e)
667 {
668  g_return_val_if_fail(e != NULL, NULL);
669  return e->category;
670 }
671 
672 static void
673 exp_setTime (QofExp * e, QofTime *h)
674 {
675  glong nanosecs;
676  QofDate *qd;
677 
678  g_return_if_fail (e != NULL);
679  if (!h)
680  return;
681  nanosecs = qof_time_get_nanosecs (h);
682  qd = qof_date_from_qtime (h);
683  qof_date_to_struct_tm (qd, &e->date, &nanosecs);
684  qof_date_free (qd);
685 }
686 
687 static void
688 exp_setType (QofExp * e, const gchar *type_string)
689 {
690  g_return_if_fail (e != NULL);
691  e->type = qof_exp_typeFromString(type_string);
692 }
693 
694 static void
695 exp_setPayment (QofExp * e, const gchar *payment_string)
696 {
697  g_return_if_fail (e != NULL);
698  e->payment = qof_exp_paymentFromString(payment_string);
699 }
700 
701 static void
702 exp_combine_currency_with_amount(QofExp *e)
703 {
704  g_return_if_fail (e != NULL);
705  if(!e->currency || e->currency_code < 0)
706  {
707  /* the gint32 currency is actually to be set BEFORE the numeric amount. :-( */
708  e->currency = qof_currency_lookup((QofInstance*)e, e->currency_code);
709  }
710  if(!e->currency)
711  {
712  PERR (" Unable to identify currency fraction."
713  " Using two decimal places.");
714  /* Amount is stored in the Palm as a string version
715  of a floating point number. */
716  e->amount = g_strdup_printf ("%.2f", e->temp_amount);
717  return;
718  }
719  switch (e->currency->fraction)
720  {
721  case 1 :
722  {
723  e->amount = g_strdup_printf ("%.0f", e->temp_amount);
724  break;
725  }
726  case 10 :
727  {
728  e->amount = g_strdup_printf ("%.1f", e->temp_amount);
729  break;
730  }
731  case 100 :
732  {
733  e->amount = g_strdup_printf ("%.2f", e->temp_amount);
734  break;
735  }
736  case 1000 :
737  {
738  e->amount = g_strdup_printf ("%.3f", e->temp_amount);
739  break;
740  }
741  default :
742  {
743  PERR (" Invalid currency fraction."
744  " Using two decimal places as default.");
745  e->amount = g_strdup_printf ("%.2f", e->temp_amount);
746  }
747  }
748 }
749 
750 static void
751 exp_setCurrency (QofExp * e, gint data)
752 {
753  g_return_if_fail (e != NULL);
754  e->currency_code = data;
755  e->currency = qof_currency_lookup((QofInstance*)e, data);
756  if(e->reset_amount)
757  exp_combine_currency_with_amount(e);
758  e->reset_amount = FALSE;
759 }
760 
761 static void
762 exp_setAmount (QofExp * e, QofNumeric h)
763 {
764  g_return_if_fail (e != NULL);
765  e->temp_amount = qof_numeric_to_double (h);
766  e->reset_amount = TRUE;
767  /* if an amount can ever be set without a currency_code,
768  this needs to be reviewed. */
771  if(e->currency) exp_combine_currency_with_amount(e);
772 }
773 
774 static void
775 exp_setVendor (QofExp * e, gchar *h)
776 {
777  g_return_if_fail (e != NULL);
778  e->vendor = g_strdup (qof_util_make_utf8(h));
779 }
780 
781 static void
782 exp_setCity (QofExp * e, gchar *h)
783 {
784  g_return_if_fail (e != NULL);
785  e->city = g_strdup (qof_util_make_utf8(h));
786 }
787 
788 static void
789 exp_setAttendees (QofExp * e, gchar *h)
790 {
791  g_return_if_fail (e != NULL);
792  e->attendees = g_strdup (qof_util_make_utf8(h));
793 }
794 
795 static void
796 exp_setNote (QofExp * e, gchar *h)
797 {
798  g_return_if_fail (e != NULL);
799  e->note = g_strdup (qof_util_make_utf8(h));
800 }
801 
802 static void
803 exp_setDistance(QofExp *e, const gchar *distance_name)
804 {
805  g_return_if_fail(e);
806  e->distance_unit = ExpenseDistancefromString(distance_name);
807 }
808 
809 static void
810 exp_setCategory(QofExp *e, gchar *n)
811 {
812  g_return_if_fail(e != NULL);
813  e->category = g_strdup(qof_util_make_utf8(n));
814 }
815 
816 static const gchar*
817 expensePrintable (gpointer instance)
818 {
819  QofExp *obj;
820 
821  obj = (QofExp*)instance;
822  if(!obj) return NULL;
823  if(exp_getType(obj))
824  return g_strconcat(exp_getType(obj), " ",
825  exp_getVendor(obj), " ", exp_getCity(obj), NULL);
826  return NULL;
827 }
828 
829 static QofObject expenses_object_def = {
830  .interface_version = QOF_OBJECT_VERSION,
831  .e_type = GPE_QOF_EXPENSES,
832  .type_label = QOF_EXPENSES_DESC,
833  .create = ((gpointer)expense_create),
834  .book_begin = NULL,
835  .book_end = NULL,
836  .is_dirty = qof_collection_is_dirty,
837  .mark_clean = qof_collection_mark_clean,
838  .foreach = qof_collection_foreach,
839  .printable = expensePrintable,
840  .version_cmp = (gint (*)(gpointer, gpointer)) qof_instance_version_cmp,
841 };
842 
843 gboolean
844 ExpensesRegister (void)
845 {
846  static QofParam params[] = {
847  { EXP_DATE, QOF_TYPE_TIME, (QofAccessFunc) exp_getTime, (QofSetterFunc) exp_setTime, NULL },
848  { EXP_TYPE, QOF_TYPE_STRING, (QofAccessFunc) exp_getType, (QofSetterFunc) exp_setType, NULL },
849  { EXP_PAYMENT, QOF_TYPE_STRING, (QofAccessFunc) exp_getPayment, (QofSetterFunc) exp_setPayment, NULL },
850  { EXP_CURRENCY, QOF_TYPE_INT32, (QofAccessFunc) exp_getCurrency, (QofSetterFunc) exp_setCurrency, NULL },
851  { EXP_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) exp_getAmount, (QofSetterFunc) exp_setAmount, NULL },
852  { EXP_VENDOR, QOF_TYPE_STRING, (QofAccessFunc) exp_getVendor, (QofSetterFunc) exp_setVendor, NULL },
853  { EXP_CITY, QOF_TYPE_STRING, (QofAccessFunc) exp_getCity, (QofSetterFunc) exp_setCity, NULL },
854  { EXP_ATTENDEES, QOF_TYPE_STRING, (QofAccessFunc) exp_getAttendees, (QofSetterFunc) exp_setAttendees, NULL },
855  { EXP_NOTE, QOF_TYPE_STRING, (QofAccessFunc) exp_getNote, (QofSetterFunc) exp_setNote, NULL },
856  { EXP_DISTANCE, QOF_TYPE_STRING, (QofAccessFunc) exp_getDistance, (QofSetterFunc) exp_setDistance, NULL },
857  { EXP_CATEGORY, QOF_TYPE_STRING, (QofAccessFunc) exp_getCategory, (QofSetterFunc) exp_setCategory, NULL },
858  { EXP_KVP, QOF_TYPE_KVP, (QofAccessFunc) qof_instance_get_slots, NULL, NULL },
859  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book, NULL, NULL },
860  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid, NULL, NULL },
861  { NULL, NULL, NULL, NULL, NULL },
862  };
863 
864  bindtextdomain (LIBRARY_GETTEXT_PACKAGE, LOCALE_DIR);
865 
866  qof_class_register (GPE_QOF_EXPENSES, NULL, params);
867  if(!qof_currency_table) populate_currencies();
868 
869  return qof_object_register (&expenses_object_def);
870 }