Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / imexporters / qif / qif.c @ eb22975b

History | View | Annotate | Download (22.5 KB)

1
/***************************************************************************
2
 $RCSfile$
3
                             -------------------
4
    cvs         : $Id$
5
    begin       : Mon Mar 01 2004
6
    copyright   : (C) 2004 by Martin Preuss
7
    email       : martin@libchipcard.de
8

9
 ***************************************************************************
10
 *          Please see toplevel file COPYING for license details           *
11
 ***************************************************************************/
12

    
13

    
14
#ifdef HAVE_CONFIG_H
15
# include <config.h>
16
#endif
17

    
18
#include "qif_p.h"
19
#include "i18n_l.h"
20
#include <gwenhywfar/debug.h>
21
#include <gwenhywfar/text.h>
22
#include <aqbanking/transaction.h>
23
#include <ctype.h>
24

    
25

    
26
GWEN_INHERIT(AB_IMEXPORTER, AH_IMEXPORTER_QIF);
27

    
28

    
29
AB_IMEXPORTER *qif_factory(AB_BANKING *ab, GWEN_DB_NODE *db)
30
{
31
  AB_IMEXPORTER *ie;
32
  AH_IMEXPORTER_QIF *ieh;
33

    
34
  ie=AB_ImExporter_new(ab, "qif");
35
  GWEN_NEW_OBJECT(AH_IMEXPORTER_QIF, ieh);
36
  GWEN_INHERIT_SETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie, ieh,
37
                       AH_ImExporterQIF_FreeData);
38
  ieh->dbData=db;
39

    
40
  AB_ImExporter_SetImportFn(ie, AH_ImExporterQIF_Import);
41
  AB_ImExporter_SetExportFn(ie, AH_ImExporterQIF_Export);
42
  /* AB_ImExporter_SetCheckFileFn(ie, AH_ImExporterQIF_CheckFile); -- not yet implemented?! */
43
  return ie;
44
}
45

    
46

    
47

    
48
void GWENHYWFAR_CB AH_ImExporterQIF_FreeData(void *bp, void *p)
49
{
50
}
51

    
52

    
53

    
54

    
55
int AH_ImExporterQIF__GetDate(AB_IMEXPORTER *ie,
56
                              GWEN_DB_NODE *params,
57
                              const char *paramName,
58
                              const char *paramDescr,
59
                              const char *paramContent,
60
                              GWEN_TIME **pti)
61
{
62
  const char *dateFormat;
63
  char dfbuf[32];
64
  int rv;
65
  GWEN_TIME *ti=0;
66
  AH_IMEXPORTER_QIF *ieqif;
67
  int first=1;
68

    
69
  assert(ie);
70
  ieqif=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie);
71
  assert(ieqif);
72

    
73
  dateFormat=GWEN_DB_GetCharValue(params, paramName, 0, 0);
74
  if (!dateFormat)
75
    dateFormat=GWEN_DB_GetCharValue(ieqif->dbData, paramName, 0, 0);
76
  if (!dateFormat)
77
    dateFormat=GWEN_DB_GetCharValue(params, "dateFormat", 0, 0);
78

    
79
  while (!ti) {
80
    if (!dateFormat) {
81
      GWEN_BUFFER *tbuf;
82
      const char *t1a=I18N_NOOP("Please enter the date format for the "
83
                                "following item:\n");
84
      const char *t1h=I18N_NOOP("<html>"
85
                                "Please enter the date format for the "
86
                                "following item:<br>");
87
      const char *t2a=I18N_NOOP
88
                      ("The following characters can be used:\n"
89
                       "- \'Y\': digit of the year\n"
90
                       "- \'M\': digit of the month\n"
91
                       "- \'D\': digit of the day\n"
92
                       "\n"
93
                       "Examples:\n"
94
                       " \"YYYY/MM/DD\" (-> 2005/02/25)\n"
95
                       " \"DD.MM.YYYY\" (-> 25.02.2005)\n"
96
                       " \"MM/DD/YY\"   (-> 02/25/05)\n");
97
      const char *t2h=I18N_NOOP
98
                      ("The following characters can be used:"
99
                       "<table>"
100
                       " <tr><td><i>Y</i></td><td>digit of the year</td></tr>\n"
101
                       " <tr><td><i>M</i></td><td>digit of the month</td></tr>\n"
102
                       " <tr><td><i>D</i></td><td>digit of the day</td></tr>\n"
103
                       "</table>\n"
104
                       "<br>"
105
                       "Examples:"
106
                       "<table>"
107
                       " <tr><td><i>YYYY/MM/DD</i></td><td>(-> 2005/02/25)</td></tr>\n"
108
                       " <tr><td><i>DD.MM.YYYY</i></td><td>(-> 25.02.2005)</td></tr>\n"
109
                       " <tr><td><i>MM/DD/YY</i></td><td>(-> 02/25/05)</td></tr>\n"
110
                       "</html>");
111

    
112
      tbuf=GWEN_Buffer_new(0, 256, 0, 1);
113
      /* ASCII version */
114
      GWEN_Buffer_AppendString(tbuf, I18N(t1a));
115
      GWEN_Buffer_AppendString(tbuf, paramDescr);
116
      GWEN_Buffer_AppendString(tbuf, " (");
117
      GWEN_Buffer_AppendString(tbuf, paramContent);
118
      GWEN_Buffer_AppendString(tbuf, " )\n");
119
      GWEN_Buffer_AppendString(tbuf, I18N(t2a));
120
      /* HTML version */
121
      GWEN_Buffer_AppendString(tbuf, I18N(t1h));
122
      GWEN_Buffer_AppendString(tbuf, paramDescr);
123
      GWEN_Buffer_AppendString(tbuf, " (");
124
      GWEN_Buffer_AppendString(tbuf, paramContent);
125
      GWEN_Buffer_AppendString(tbuf, " )\n");
126
      GWEN_Buffer_AppendString(tbuf, I18N(t2h));
127

    
128
      rv=GWEN_Gui_InputBox(0,
129
                           first?I18N("Enter Date Format"):
130
                           I18N("Enter Correct Date Format"),
131
                           GWEN_Buffer_GetStart(tbuf),
132
                           dfbuf, 4,  sizeof(dfbuf)-1,
133
                           0);
134
      GWEN_Buffer_free(tbuf);
135
      if (rv) {
136
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
137
        return rv;
138
      }
139
      dateFormat=dfbuf;
140

    
141
      ti=GWEN_Time_fromString(paramContent, dateFormat);
142
      if (ti) {
143
        /* store particular date format */
144
        GWEN_DB_SetCharValue(ieqif->dbData,
145
                             GWEN_DB_FLAGS_OVERWRITE_VARS,
146
                             paramName, dfbuf);
147
        break;
148
      }
149
      dateFormat=0;
150
    }
151
    else
152
      break;
153
  } /* for */
154

    
155
  *pti=ti;
156
  return 0;
157
}
158

    
159

    
160

    
161
int AH_ImExporterQIF__GetValue(AB_IMEXPORTER *ie,
162
                               GWEN_DB_NODE *params,
163
                               const char *paramName,
164
                               const char *paramDescr,
165
                               const char *paramContent,
166
                               AB_VALUE **pv)
167
{
168
  const char *s;
169
  char komma = 0;
170
  char fixpoint = 0;
171
  AH_IMEXPORTER_QIF *ieqif;
172
  char numbuf[64];
173
  int i;
174
  double dval;
175
  AB_VALUE *v;
176

    
177
  assert(ie);
178
  ieqif=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie);
179
  assert(ieqif);
180

    
181
  /* get komma character */
182
  s=GWEN_DB_GetCharValue(params, "value/komma", 0, 0);
183
  if (!s)
184
    s=GWEN_DB_GetCharValue(ieqif->dbData, "value/komma", 0, 0);
185
  if (s)
186
    komma=*s;
187
  /* get fixpoint character */
188
  s=GWEN_DB_GetCharValue(params, "value/fixpoint", 0, 0);
189
  if (!s)
190
    s=GWEN_DB_GetCharValue(ieqif->dbData, "value/fixpoint", 0, 0);
191
  if (s)
192
    fixpoint=*s;
193

    
194
  if (!fixpoint) {
195
    const char *lastKommaPos = NULL;
196
    char lastKommaChar=0;
197
    int komma1Count=0;
198
    int komma2Count=0;
199
    int kommaTypeCount=0;
200

    
201
    fixpoint=0;
202
    komma=0;
203

    
204
    /* nothing known about fixpoint, elaborate */
205
    s=paramContent;
206
    while (*s) {
207
      if (*s=='.' || *s==',') {
208
        if (*s==',')
209
          komma1Count++;
210
        else
211
          komma2Count++;
212
        lastKommaChar=*s;
213
        lastKommaChar=*s;
214
        kommaTypeCount++;
215
        lastKommaPos=s;
216
      }
217
      s++;
218
    } /* while */
219
    if (((komma1Count+komma2Count)==1) && lastKommaPos) {
220
      int i=0;
221

    
222
      /* only one komma, check for digits behind it */
223
      s=lastKommaPos;
224
      s++;
225
      while (*s && isdigit(*s)) {
226
        s++;
227
        i++;
228
      }
229
      if (i<3) {
230
        /* most likely got the fixpoint */
231
        fixpoint=lastKommaChar;
232
      }
233
    }
234
    else if ((komma1Count==1 && komma2Count>0) ||
235
             (komma2Count==1 && komma1Count>0)) {
236
      if (komma1Count==1) {
237
        fixpoint=',';
238
        komma='.';
239
      }
240
      else {
241
        fixpoint='.';
242
        komma=',';
243
      }
244
    }
245
    else {
246
      GWEN_BUFFER *tbuf;
247
      int rv;
248
      const char *t1a=
249
        I18N_NOOP("The following value could not be parsed: \n");
250
      const char *t2a=
251
        I18N_NOOP("There are now two possibilities of what character\n"
252
                  "represents the decimal fixpoint:\n"
253
                  " 1) \'.\' (as in \"123.45\")\n"
254
                  " 2) \',\' (as in \"123,45\")\n"
255
                  "What is the fixpoint in the value above?");
256
      const char *t1h=
257
        I18N_NOOP("<html>The following value could not be parsed: <br>");
258
      const char *t2h=
259
        I18N_NOOP("<br>"
260
                  "There are now two possibilities of what character "
261
                  "represents the decimal fixpoint: "
262
                  "<ol>"
263
                  " <li>\'.\' (as in \"123.45\")</li>\n"
264
                  " <li>\',\' (as in \"123,45\")</li>\n"
265
                  "</ol>"
266
                  "What is the fixpoint in the value above?"
267
                  "</html>");
268

    
269
      /* this is weird, ask the user */
270
      tbuf=GWEN_Buffer_new(0, 256, 0, 1);
271
      GWEN_Buffer_AppendString(tbuf, t1a);
272
      GWEN_Buffer_AppendString(tbuf, paramContent);
273
      GWEN_Buffer_AppendString(tbuf, t2a);
274
      GWEN_Buffer_AppendString(tbuf, t1h);
275
      GWEN_Buffer_AppendString(tbuf, paramContent);
276
      GWEN_Buffer_AppendString(tbuf, t2h);
277
      rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN |
278
                             GWEN_GUI_MSG_FLAGS_SEVERITY_NORMAL |
279
                             GWEN_GUI_MSG_FLAGS_CONFIRM_B1,
280
                             I18N("Value Parsing"),
281
                             I18N(GWEN_Buffer_GetStart(tbuf)),
282
                             I18N("Possibility 1"),
283
                             I18N("Possibility 2"),
284
                             0,
285
                             0);
286
      GWEN_Buffer_free(tbuf);
287
      if (rv==1) {
288
        fixpoint='.';
289
        komma=',';
290
      }
291
      else if (rv==2) {
292
        fixpoint=',';
293
        komma='.';
294
      }
295
      else {
296
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
297
        return rv;
298
      }
299
    }
300
  } /* if !fixpoint */
301

    
302
  /* now we know what the fixpoint is, store it */
303
  numbuf[0]=komma;
304
  numbuf[1]=0;
305
  GWEN_DB_SetCharValue(ieqif->dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
306
                       "value/komma", numbuf);
307
  numbuf[0]=fixpoint;
308
  GWEN_DB_SetCharValue(ieqif->dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
309
                       "value/fixpoint", numbuf);
310

    
311
  i=0;
312
  s=paramContent;
313
  while (*s && i<(int)sizeof(numbuf)) {
314
    if (*s==fixpoint)
315
      numbuf[i++]=',';
316
    else if (*s=='-' || *s=='+' || *s==isdigit(*s))
317
      numbuf[i++]=*s;
318
    else if (*s!=komma) {
319
      DBG_ERROR(AQBANKING_LOGDOMAIN,
320
                "Bad character in value string");
321
      return GWEN_ERROR_BAD_DATA;
322
    }
323
  }
324
  if (i>=(int)sizeof(numbuf)) {
325
    DBG_ERROR(AQBANKING_LOGDOMAIN,
326
              "Value string too long");
327
    return GWEN_ERROR_BAD_DATA;
328
  }
329
  numbuf[i]=0;
330

    
331
  if (GWEN_Text_StringToDouble(numbuf, &dval)) {
332
    DBG_ERROR(AQBANKING_LOGDOMAIN,
333
              "Value string does not contain a floating point value.");
334
    return GWEN_ERROR_BAD_DATA;
335
  }
336

    
337
  v=AB_Value_fromDouble(dval);
338
  *pv=v;
339
  return 0;
340
}
341

    
342

    
343

    
344
int AH_ImExporterQIF__ImportAccount(AB_IMEXPORTER *ie,
345
                                    AB_IMEXPORTER_CONTEXT *iec,
346
                                    GWEN_BUFFEREDIO *bio,
347
                                    GWEN_BUFFER *buf,
348
                                    GWEN_DB_NODE *params)
349
{
350
  AH_IMEXPORTER_QIF *ieqif;
351
  GWEN_DB_NODE *dbData;
352
  AB_IMEXPORTER_ACCOUNTINFO *iea = 0;
353
  int done=0;
354
  const char *s;
355
  GWEN_TIME *ti=0;
356
  AB_VALUE *vCreditLine=0;
357
  AB_VALUE *vBalance=0;
358

    
359
  assert(ie);
360
  ieqif=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie);
361
  assert(ieqif);
362

    
363
  dbData=GWEN_DB_Group_new("data");
364
  while (!done) {
365
    const char *p;
366

    
367
    if (!GWEN_Buffer_GetUsedBytes(buf)) {
368
      int err;
369

    
370
      if (GWEN_BufferedIO_CheckEOF(bio)) {
371
        done=1;
372
        continue;
373
      }
374

    
375
      err=GWEN_BufferedIO_ReadLine2Buffer(bio, buf);
376
      if (err) {
377
        DBG_ERROR_ERR(AQBANKING_LOGDOMAIN, err);
378
        GWEN_DB_Group_free(dbData);
379
        return err;
380
      }
381
    }
382

    
383
    p=GWEN_Buffer_GetStart(buf);
384
    while (isspace(*p))
385
      p++;
386

    
387
    switch (toupper(*p)) {
388
    case 'N': /* account name */
389
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
390
                           "name", p+1);
391
      break;
392
    case 'T': /* account type */
393
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
394
                           "type", p+1);
395
      break;
396
    case 'D': /* description */
397
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
398
                           "descr", p+1);
399
      break;
400
    case 'L': /* credit line (credit card accounts only */
401
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
402
                           "creditLine", p+1);
403
      break;
404
    case '/': /* date of statement balance */
405
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
406
                           "date", p+1);
407
      break;
408
    case '$': /* statement balance */
409
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
410
                           "balance", p+1);
411
      break;
412
    case '^': /* end of record */
413
      done=1;
414
      break;
415
    default: /* unknown line, ignore */
416
      DBG_WARN(AQBANKING_LOGDOMAIN,
417
               "Unknown item \"%s\", ignoring",
418
               GWEN_Buffer_GetStart(buf));
419
    } /* switch */
420

    
421
    GWEN_Buffer_Reset(buf);
422
  } /* while not end of block reached */
423

    
424
  /* find account info by account name */
425
  s=GWEN_DB_GetCharValue(dbData, "name", 0, 0);
426
  if (s) {
427
    iea=AB_ImExporterContext_GetFirstAccountInfo(iec);
428
    while (iea) {
429
      if (strcasecmp(AB_ImExporterAccountInfo_GetAccountName(iea), s)==0)
430
        break;
431
      iea=AB_ImExporterContext_GetNextAccountInfo(iec);
432
    } /* while */
433
  }
434

    
435
  if (!iea) {
436
    /* not found, add it */
437
    iea=AB_ImExporterAccountInfo_new();
438
    AB_ImExporterContext_AddAccountInfo(iec, iea);
439
    /* set account info */
440
    if (s)
441
      AB_ImExporterAccountInfo_SetAccountName(iea, s);
442
    s=GWEN_DB_GetCharValue(dbData, "descr", 0, 0);
443
    if (s)
444
      AB_ImExporterAccountInfo_SetDescription(iea, s);
445
    s=GWEN_DB_GetCharValue(dbData, "type", 0, 0);
446
    if (s) {
447
      if (strcasecmp(s, "bank")==0)
448
        AB_ImExporterAccountInfo_SetType(iea, AB_AccountType_Bank);
449
      else if (strcasecmp(s, "Invst")==0)
450
        AB_ImExporterAccountInfo_SetType(iea, AB_AccountType_Investment);
451
      else if (strcasecmp(s, "CCard")==0)
452
        AB_ImExporterAccountInfo_SetType(iea, AB_AccountType_CreditCard);
453
      else if (strcasecmp(s, "Cash")==0)
454
        AB_ImExporterAccountInfo_SetType(iea, AB_AccountType_Cash);
455
      else
456
        AB_ImExporterAccountInfo_SetType(iea, AB_AccountType_Unknown);
457
    }
458
  }
459
  assert(iea);
460
  ieqif->currentAccount=iea;
461

    
462
  s=GWEN_DB_GetCharValue(dbData, "date", 0, 0);
463
  if (s) {
464
    int rv;
465

    
466
    rv=AH_ImExporterQIF__GetDate(ie, params,
467
                                 "account/statement/dateFormat",
468
                                 I18N("Account statement date"),
469
                                 s, &ti);
470
    if (rv) {
471
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
472
      GWEN_DB_Group_free(dbData);
473
      return rv;
474
    }
475
  }/* if date */
476

    
477
  s=GWEN_DB_GetCharValue(dbData, "creditLine", 0, 0);
478
  if (s) {
479
    int rv;
480

    
481
    rv=AH_ImExporterQIF__GetValue(ie, params,
482
                                  "account/statement/creditLineFormat",
483
                                  I18N("Account statement credit line value"),
484
                                  s, &vCreditLine);
485
    if (rv) {
486
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
487
      GWEN_Time_free(ti);
488
      GWEN_DB_Group_free(dbData);
489
      return rv;
490
    }
491
  }/* if date */
492

    
493
  s=GWEN_DB_GetCharValue(dbData, "balance", 0, 0);
494
  if (s) {
495
    int rv;
496

    
497
    rv=AH_ImExporterQIF__GetValue(ie, params,
498
                                  "account/statement/balanceFormat",
499
                                  I18N("Account statement balance value"),
500
                                  s, &vBalance);
501
    if (rv) {
502
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
503
      AB_Value_free(vCreditLine);
504
      GWEN_Time_free(ti);
505
      GWEN_DB_Group_free(dbData);
506
      return rv;
507
    }
508
  }/* if date */
509

    
510
  if (ti && (vBalance || vCreditLine)) {
511
    AB_BALANCE *balance=0;
512
    AB_ACCOUNT_STATUS *ast=0;
513

    
514
    if (vBalance && ti)
515
      balance=AB_Balance_new(vBalance, ti);
516

    
517
    ast=AB_AccountStatus_new();
518
    if (ti)
519
      AB_AccountStatus_SetTime(ast, ti);
520
    if (vCreditLine)
521
      AB_AccountStatus_SetBankLine(ast, vCreditLine);
522
    if (balance)
523
      AB_AccountStatus_SetBookedBalance(ast, balance);
524
    /* add account status */
525
    AB_ImExporterAccountInfo_AddAccountStatus(iea, ast);
526

    
527
    AB_AccountStatus_free(ast);
528
    AB_Balance_free(balance);
529
  }
530
  AB_Value_free(vBalance);
531
  AB_Value_free(vCreditLine);
532
  GWEN_Time_free(ti);
533
  GWEN_DB_Group_free(dbData);
534

    
535
  return 0;
536
}
537

    
538

    
539

    
540
int AH_ImExporterQIF__ImportBank(AB_IMEXPORTER *ie,
541
                                 AB_IMEXPORTER_CONTEXT *iec,
542
                                 GWEN_BUFFEREDIO *bio,
543
                                 GWEN_BUFFER *buf,
544
                                 GWEN_DB_NODE *params)
545
{
546
  AH_IMEXPORTER_QIF *ieqif;
547
  GWEN_DB_NODE *dbData;
548
  AB_IMEXPORTER_ACCOUNTINFO *iea;
549
  int done=0;
550
  const char *s;
551
  GWEN_TIME *ti=0;
552
  AB_VALUE *vAmount=0;
553
  GWEN_DB_NODE *dbCurrentSplit=0;
554
  AB_TRANSACTION *t=0;
555

    
556
  assert(ie);
557
  ieqif=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie);
558
  assert(ieqif);
559

    
560
  dbData=GWEN_DB_Group_new("data");
561
  while (!done) {
562
    const char *p;
563

    
564
    if (!GWEN_Buffer_GetUsedBytes(buf)) {
565
      int err;
566

    
567
      if (GWEN_BufferedIO_CheckEOF(bio)) {
568
        done=1;
569
        continue;
570
      }
571

    
572
      err=GWEN_BufferedIO_ReadLine2Buffer(bio, buf);
573
      if (err) {
574
        DBG_ERROR_ERR(AQBANKING_LOGDOMAIN, err);
575
        GWEN_DB_Group_free(dbData);
576
        return err;
577
      }
578
    }
579

    
580
    p=GWEN_Buffer_GetStart(buf);
581
    while (isspace(*p))
582
      p++;
583

    
584
    switch (toupper(*p)) {
585
    case 'S':
586
      dbCurrentSplit=GWEN_DB_GetGroup(dbData,
587
                                      GWEN_PATH_FLAGS_CREATE_GROUP,
588
                                      "split");
589
      assert(dbCurrentSplit);
590
      GWEN_DB_SetCharValue(dbCurrentSplit,
591
                           GWEN_DB_FLAGS_OVERWRITE_VARS,
592
                           "category", p+1);
593
      break;
594
    case '$': /* split amount */
595
      assert(dbCurrentSplit);
596
      GWEN_DB_SetCharValue(dbCurrentSplit, GWEN_DB_FLAGS_OVERWRITE_VARS,
597
                           "amount", p+1);
598
      break;
599
    case 'E': /* split memo */
600
      assert(dbCurrentSplit);
601
      GWEN_DB_SetCharValue(dbCurrentSplit, GWEN_DB_FLAGS_OVERWRITE_VARS,
602
                           "memo", p+1);
603
      break;
604

    
605
    case 'D': /* date */
606
      GWEN_DB_SetCharValue(dbData,
607
                           GWEN_DB_FLAGS_OVERWRITE_VARS,
608
                           "date", p+1);
609
      break;
610
    case 'N': /* reference */
611
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
612
                           "reference", p+1);
613
      break;
614
    case 'T': /* amount */
615
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
616
                           "amount", p+1);
617
      break;
618
    case 'P': /* payee */
619
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_DEFAULT,
620
                           "payee", p+1);
621
      break;
622
    case 'M': /* memo */
623
      GWEN_DB_SetCharValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
624
                           "memo", p+1);
625
      break;
626
    case 'A': /* address */
627
      GWEN_DB_SetCharValue(dbData,
628
                           GWEN_DB_FLAGS_DEFAULT,
629
                           "address", p+1);
630
      break;
631
    case 'L': /* category */
632
      GWEN_DB_SetCharValue(dbData,
633
                           GWEN_DB_FLAGS_OVERWRITE_VARS,
634
                           "category", p+1);
635
      break;
636
    case 'C': /* cleared status */
637
      GWEN_DB_SetCharValue(dbData,
638
                           GWEN_DB_FLAGS_OVERWRITE_VARS,
639
                           "cleared", p+1);
640
      break;
641
    case '^': /* end of record */
642
      done=1;
643
      break;
644
    default: /* unknown line, ignore */
645
      DBG_WARN(AQBANKING_LOGDOMAIN,
646
               "Unknown item \"%s\", ignoring",
647
               GWEN_Buffer_GetStart(buf));
648
    } /* switch */
649

    
650
    GWEN_Buffer_Reset(buf);
651
  } /* while not end of block reached */
652

    
653
  iea=ieqif->currentAccount;
654
  assert(iea);
655

    
656
  s=GWEN_DB_GetCharValue(dbData, "date", 0, 0);
657
  if (s) {
658
    int rv;
659

    
660
    rv=AH_ImExporterQIF__GetDate(ie, params,
661
                                 "account/statement/dateFormat",
662
                                 I18N("Account statement date"),
663
                                 s, &ti);
664
    if (rv) {
665
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
666
      GWEN_DB_Group_free(dbData);
667
      return rv;
668
    }
669
  }/* if date */
670

    
671
  s=GWEN_DB_GetCharValue(dbData, "amount", 0, 0);
672
  if (s) {
673
    int rv;
674

    
675
    rv=AH_ImExporterQIF__GetValue(ie, params,
676
                                  "bank/statement/amountFormat",
677
                                  I18N("Transaction statement amount value"),
678
                                  s, &vAmount);
679
    if (rv) {
680
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
681
      GWEN_Time_free(ti);
682
      GWEN_DB_Group_free(dbData);
683
      return rv;
684
    }
685
  }/* if date */
686

    
687
  t=AB_Transaction_new();
688
  if (ti) {
689
    AB_Transaction_SetValutaDate(t, ti);
690
    AB_Transaction_SetDate(t, ti);
691
  }
692
  if (vAmount)
693
    AB_Transaction_SetValue(t, vAmount);
694

    
695
  s=GWEN_DB_GetCharValue(dbData, "payee", 0, 0);
696
  if (s)
697
    AB_Transaction_AddRemoteName(t, s, 0);
698
  s=GWEN_DB_GetCharValue(dbData, "memo", 0, 0);
699
  if (s)
700
    AB_Transaction_AddPurpose(t, s, 0);
701

    
702
  DBG_INFO(AQBANKING_LOGDOMAIN, "Adding transaction");
703
  AB_ImExporterAccountInfo_AddTransaction(iea, t);
704

    
705
  AB_Value_free(vAmount);
706
  GWEN_Time_free(ti);
707
  GWEN_DB_Group_free(dbData);
708

    
709
  return 0;
710
}
711

    
712

    
713

    
714

    
715

    
716

    
717

    
718

    
719

    
720

    
721
int AH_ImExporterQIF_Import(AB_IMEXPORTER *ie,
722
                            AB_IMEXPORTER_CONTEXT *ctx,
723
                            GWEN_BUFFEREDIO *bio,
724
                            GWEN_DB_NODE *params)
725
{
726
  GWEN_BUFFER *buf;
727
  char lastSectionName[256];
728
  AH_IMEXPORTER_QIF *ieqif;
729

    
730
  assert(ie);
731
  ieqif=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AH_IMEXPORTER_QIF, ie);
732
  assert(ieqif);
733

    
734
  buf=GWEN_Buffer_new(0, 256, 0, 1);
735

    
736
  while (!GWEN_BufferedIO_CheckEOF(bio)) {
737
    int err;
738
    const char *p;
739
    int rv;
740

    
741
    err=GWEN_BufferedIO_ReadLine2Buffer(bio, buf);
742
    if (err) {
743
      DBG_ERROR_ERR(AQBANKING_LOGDOMAIN, err);
744
      GWEN_Buffer_free(buf);
745
      return err;
746
    }
747
    p=GWEN_Buffer_GetStart(buf);
748
    while (isspace(*p))
749
      p++;
750

    
751
    if (*p=='!') {
752
      p++;
753
      if (strlen(p)>=(int)sizeof(lastSectionName)) {
754
        DBG_ERROR(AQBANKING_LOGDOMAIN,
755
                  "Buffer too small. Internal error, should not occurr.");
756
        abort();
757
      }
758
      strcpy(lastSectionName, p);
759
      GWEN_Buffer_Reset(buf);
760
    }
761

    
762
    if (lastSectionName[0]) {
763
      if (strcasecmp(lastSectionName, "Account")==0)
764
        rv=AH_ImExporterQIF__ImportAccount(ie, ctx, bio, buf, params);
765
      else {
766
        DBG_WARN(AQBANKING_LOGDOMAIN,
767
                 "Unknown section \"%s\", ignoring",
768
                 GWEN_Buffer_GetStart(buf));
769
        lastSectionName[0]=0;
770
        rv=0; /* ignore this section */
771
      }
772
    }
773

    
774
    GWEN_Buffer_Reset(buf);
775
  } /* while */
776

    
777
  return 0;
778
}
779

    
780

    
781

    
782
int AH_ImExporterQIF_Export(AB_IMEXPORTER *ie,
783
                            AB_IMEXPORTER_CONTEXT *ctx,
784
                            GWEN_BUFFEREDIO *bio,
785
                            GWEN_DB_NODE *params)
786
{
787
  return GWEN_ERROR_NOT_SUPPORTED;
788
}
789

    
790

    
791