Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / imexporters / yellownet / yellownet.c @ f4a16f5b

History | View | Annotate | Download (11.7 KB)

1
/***************************************************************************
2
    begin       : Mon Mar 01 2004
3
    copyright   : (C) 2018 by Martin Preuss
4
    email       : martin@libchipcard.de
5

6
 ***************************************************************************
7
 *          Please see toplevel file COPYING for license details           *
8
 ***************************************************************************/
9

    
10
#ifdef HAVE_CONFIG_H
11
# include <config.h>
12
#endif
13

    
14
#include "yellownet_p.h"
15
#include "i18n_l.h"
16
#include <aqbanking/banking.h>
17
#include <gwenhywfar/debug.h>
18
#include <gwenhywfar/misc.h>
19
#include <gwenhywfar/gui.h>
20
#include <gwenhywfar/inherit.h>
21
#include <gwenhywfar/xml.h>
22
#include <gwenhywfar/text.h>
23
#include <gwenhywfar/fastbuffer.h>
24
#include <gwenhywfar/syncio_file.h>
25

    
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <fcntl.h>
29
#include <errno.h>
30

    
31

    
32
GWEN_INHERIT(AB_IMEXPORTER, AB_IMEXPORTER_YELLOWNET);
33

    
34

    
35

    
36
AB_IMEXPORTER *AB_ImExporterYellowNet_new(AB_BANKING *ab){
37
  AB_IMEXPORTER *ie;
38
  AB_IMEXPORTER_YELLOWNET *ieh;
39

    
40
  ie=AB_ImExporter_new(ab, "yellownet");
41
  GWEN_NEW_OBJECT(AB_IMEXPORTER_YELLOWNET, ieh);
42
  GWEN_INHERIT_SETDATA(AB_IMEXPORTER, AB_IMEXPORTER_YELLOWNET, ie, ieh,
43
                       AB_ImExporterYN_FreeData);
44
  AB_ImExporter_SetImportFn(ie, AB_ImExporterYN_Import);
45
  AB_ImExporter_SetCheckFileFn(ie, AB_ImExporterYN_CheckFile);
46
  return ie;
47
}
48

    
49

    
50

    
51
void GWENHYWFAR_CB AB_ImExporterYN_FreeData(void *bp, void *p){
52
  AB_IMEXPORTER_YELLOWNET *ieh;
53

    
54
  ieh=(AB_IMEXPORTER_YELLOWNET*)p;
55
  GWEN_FREE_OBJECT(ieh);
56
}
57

    
58

    
59

    
60
AB_IMEXPORTER_ACCOUNTINFO*
61
AB_ImExporterYN__ReadAccountInfo(AB_IMEXPORTER *ie,
62
                                 AB_IMEXPORTER_CONTEXT *ctx,
63
                                 GWEN_XMLNODE *doc) {
64
  GWEN_XMLNODE *n;
65
  AB_IMEXPORTER_ACCOUNTINFO *ai;
66

    
67
  ai=AB_ImExporterAccountInfo_new();
68

    
69
  n=GWEN_XMLNode_FindFirstTag(doc, "SG2", 0, 0);
70
  if (n)
71
    n=GWEN_XMLNode_FindFirstTag(n, "FII", 0, 0);
72
  if (n) {
73
    GWEN_XMLNODE *nn;
74
    const char *s;
75

    
76
    nn=GWEN_XMLNode_FindFirstTag(n, "C078", 0, 0);
77
    if (nn) {
78
      GWEN_XMLNODE *nnn;
79

    
80
      /* account number */
81
      s=GWEN_XMLNode_GetCharValue(nn, "D_3194", 0);
82
      if (s)
83
        AB_ImExporterAccountInfo_SetAccountNumber(ai, s);
84
      /* IBAN */
85
      s=GWEN_XMLNode_GetCharValue(nn, "D_3192", 0);
86
      if (s)
87
        AB_ImExporterAccountInfo_SetIban(ai, s);
88
      /* currency */
89
      nnn=GWEN_XMLNode_FindFirstTag(nn, "D_6345", 0, 0);
90
      if (nnn) {
91
        s=GWEN_XMLNode_GetProperty(nnn, "value", 0);
92
        if (s)
93
          AB_ImExporterAccountInfo_SetCurrency(ai, s);
94
      }
95
    }
96

    
97
    /* account number */
98
    s=GWEN_XMLNode_GetCharValue(n, "PF:D_5388", 0);
99
    if (s)
100
      AB_ImExporterAccountInfo_SetAccountName(ai, s);
101
  }
102

    
103
  /* owner name */
104
  n=GWEN_XMLNode_GetNodeByXPath(doc, "SG3[1]/NAD",
105
                                GWEN_PATH_FLAGS_NAMEMUSTEXIST);
106
  if (n) {
107
    GWEN_XMLNODE *nn;
108

    
109
    nn=GWEN_XMLNode_FindFirstTag(n, "D_3035", 0, 0);
110
    if (nn) {
111
      const char *s;
112

    
113
      s=GWEN_XMLNode_GetProperty(nn, "Value", 0);
114
      if (s && strcasecmp(s, "HQ")==0) {
115
        nn=GWEN_XMLNode_FindFirstTag(n, "C058", 0, 0);
116
        if (nn) {
117
          s=GWEN_XMLNode_GetCharValue(nn, "D_3124", 0);
118
          if (s && *s) {
119
            GWEN_BUFFER *xbuf;
120

    
121
            xbuf=GWEN_Buffer_new(0, 256, 0, 1);
122
            AB_ImExporter_Iso8859_1ToUtf8(s, strlen(s), xbuf);
123
            AB_ImExporterAccountInfo_SetOwner(ai, GWEN_Buffer_GetStart(xbuf));
124
            GWEN_Buffer_free(xbuf);
125
          }
126
        }
127
      }
128
    }
129
  }
130

    
131
  return ai;
132
}
133

    
134

    
135

    
136
AB_VALUE *AB_ImExporterYN__ReadValue(AB_IMEXPORTER *ie,
137
                                     GWEN_XMLNODE *node,
138
                                     int value) {
139
  GWEN_XMLNODE *n;
140
  AB_VALUE *val=0;
141

    
142
  n=GWEN_XMLNode_FindFirstTag(node, "C516", 0, 0);
143
  if (n) {
144
    GWEN_XMLNODE *nn;
145
    int v=0;
146

    
147
    nn=GWEN_XMLNode_FindFirstTag(n, "D_5025", 0, 0);
148
    if (nn)
149
      v=atoi(GWEN_XMLNode_GetProperty(nn, "Value", "0"));
150
    if (value==0 || v==value) {
151
      const char *sValue;
152
      const char *sSign;
153

    
154
      sValue=GWEN_XMLNode_GetCharValue(n, "D_5004", 0);
155
      sSign=GWEN_XMLNode_GetCharValue(node, "PF:D_5003", 0);
156

    
157
      if (sValue) {
158
        val=AB_Value_fromString(sValue);
159
        if (val && sSign && strcmp(sSign, "-")==0)
160
          AB_Value_Negate(val);
161
      }
162
    }
163
  }
164

    
165
  return val;
166
}
167

    
168

    
169

    
170
GWEN_DATE *AB_ImExporterYN__ReadDate(AB_IMEXPORTER *ie, GWEN_XMLNODE *node, int value) {
171
  GWEN_XMLNODE *n;
172
  GWEN_DATE *da=NULL;
173

    
174
  n=GWEN_XMLNode_GetNodeByXPath(node, "C507", GWEN_PATH_FLAGS_NAMEMUSTEXIST);
175
  if (n) {
176
    GWEN_XMLNODE *nn;
177
    int v=0;
178

    
179
    nn=GWEN_XMLNode_FindFirstTag(n, "D_2005", 0, 0);
180
    if (nn)
181
      v=atoi(GWEN_XMLNode_GetProperty(nn, "Value", "0"));
182

    
183
    if (value==0 || v==value) {
184
      const char *s;
185

    
186
      s=GWEN_XMLNode_GetCharValue(n, "D_2380", 0);
187
      if (s)
188
        da=GWEN_Date_fromStringWithTemplate(s, "YYYYMMDD");
189
    }
190
  }
191

    
192
  return da;
193
}
194

    
195

    
196

    
197
AB_TRANSACTION *AB_ImExporterYN__ReadLNE_LNS(AB_IMEXPORTER *ie,
198
                                             AB_IMEXPORTER_ACCOUNTINFO *ai,
199
                                             GWEN_XMLNODE *node) {
200
    AB_TRANSACTION *t;
201
    GWEN_XMLNODE *nn;
202
    GWEN_DATE *da=NULL;
203
    AB_VALUE *val=NULL;
204

    
205
    t=AB_Transaction_new();
206

    
207
    /* get date */
208
    nn=GWEN_XMLNode_FindFirstTag(node, "DTM", 0, 0);
209
    if (nn)
210
      da=AB_ImExporterYN__ReadDate(ie, nn, 209);
211
    AB_Transaction_SetValutaDate(t, da);
212
    GWEN_Date_free(da);
213
    da=NULL;
214

    
215
    /* read amount */
216
    nn=GWEN_XMLNode_FindFirstTag(node, "MOA", 0, 0);
217
    if (nn) {
218
      /* Gutschrift */
219
      val=AB_ImExporterYN__ReadValue(ie, nn, 210);
220
      if (val) {
221
        if (AB_Value_IsZero(val)) {
222
          AB_Value_free(val);
223
          val=NULL;
224
        }
225
      }
226
      if (val==NULL) {
227
        val=AB_ImExporterYN__ReadValue(ie, nn, 211);
228
        if (val)
229
          AB_Value_Negate(val);
230
      }
231
    }
232
    if (val==NULL)
233
      val=AB_Value_new();
234
    AB_Value_SetCurrency(val, AB_ImExporterAccountInfo_GetCurrency(ai));
235
    AB_Transaction_SetValue(t, val);
236
    AB_Value_free(val);
237
    val=0;
238

    
239
    /* read purpose */
240
    nn=GWEN_XMLNode_GetNodeByXPath(node, "FTX/C108",
241
                                   GWEN_PATH_FLAGS_NAMEMUSTEXIST);
242
    if (nn) {
243
      GWEN_XMLNODE *nnn;
244

    
245
      nnn=GWEN_XMLNode_FindFirstTag(nn, "D_4440", 0, 0);
246
      while(nnn) {
247
        GWEN_XMLNODE *nData;
248
  
249
        nData=GWEN_XMLNode_GetFirstData(nnn);
250
        if (nData) {
251
          const char *s;
252

    
253
          s=GWEN_XMLNode_GetData(nData);
254
          if (s) {
255
            GWEN_BUFFER *xbuf;
256

    
257
            xbuf=GWEN_Buffer_new(0, 256, 0, 1);
258
            AB_ImExporter_Iso8859_1ToUtf8(s, strlen(s), xbuf);
259
            AB_Transaction_AddPurposeLine(t, GWEN_Buffer_GetStart(xbuf));
260
            GWEN_Buffer_free(xbuf);
261
          }
262
        }
263
        nnn=GWEN_XMLNode_FindNextTag(nnn, "D_4440", 0, 0);
264
      }
265
    }
266

    
267
    return t;
268
}
269

    
270

    
271

    
272
int AB_ImExporterYN__ReadTransactions(AB_IMEXPORTER *ie,
273
                                      AB_IMEXPORTER_ACCOUNTINFO *ai,
274
                                      GWEN_XMLNODE *doc) {
275
  GWEN_XMLNODE *n;
276

    
277
  n=GWEN_XMLNode_FindFirstTag(doc, "SG4", 0, 0);
278
  while(n) {
279
    GWEN_XMLNODE *nn;
280

    
281
    nn=GWEN_XMLNode_GetNodeByXPath(n, "LIN/PF:D_0805",
282
                                   GWEN_PATH_FLAGS_NAMEMUSTEXIST);
283
    if (nn) {
284
      const char *s;
285

    
286
      s=GWEN_XMLNode_GetProperty(nn, "Value", 0);
287
      if (s &&
288
          (strcasecmp(s, "LNE")==0 ||
289
           strcasecmp(s, "LNS")==0)
290
         ) {
291
        nn = GWEN_XMLNode_FindFirstTag(n, "SG6", 0, 0);
292
        while(nn) {
293
          AB_TRANSACTION *t;
294
          const char *s;
295

    
296
          t=AB_ImExporterYN__ReadLNE_LNS(ie, ai, nn);
297
          s=AB_ImExporterAccountInfo_GetAccountNumber(ai);
298
          AB_Transaction_SetLocalAccountNumber(t, s);
299
          s=AB_ImExporterAccountInfo_GetIban(ai);
300
          AB_Transaction_SetLocalIban(t, s);
301
          AB_ImExporterAccountInfo_AddTransaction(ai, t);
302

    
303
          nn=GWEN_XMLNode_FindNextTag(nn, "SG6", 0, 0);
304
        }
305
      }
306
    }
307

    
308
    n=GWEN_XMLNode_FindNextTag(n, "SG4", 0, 0);
309
  }
310

    
311
  return 0;
312
}
313

    
314

    
315

    
316
int AB_ImExporterYN__ReadAccountStatus(AB_IMEXPORTER *ie,
317
                                       AB_IMEXPORTER_ACCOUNTINFO *ai,
318
                                       GWEN_XMLNODE *doc) {
319
  GWEN_XMLNODE *n;
320

    
321
  n=GWEN_XMLNode_FindFirstTag(doc, "SG4", 0, 0);
322
  while(n) {
323
    GWEN_XMLNODE *nn;
324

    
325
    nn=GWEN_XMLNode_GetNodeByXPath(n, "LIN/PF:D_0805",
326
                                   GWEN_PATH_FLAGS_NAMEMUSTEXIST);
327
    if (nn) {
328
      const char *s;
329

    
330
      s=GWEN_XMLNode_GetProperty(nn, "Value", 0);
331
      if (s && strcasecmp(s, "LEN")==0) {
332
        GWEN_XMLNODE *nnn;
333
        GWEN_DATE *dt=0;
334
        AB_VALUE *val=0;
335

    
336
        /* read time */
337
        nnn=GWEN_XMLNode_GetNodeByXPath(n, "SG5/DTM", GWEN_PATH_FLAGS_NAMEMUSTEXIST);
338
        if (nnn)
339
          dt=AB_ImExporterYN__ReadDate(ie, nnn, 202);
340

    
341
        /* read value */
342
        nnn=GWEN_XMLNode_GetNodeByXPath(n, "SG5/MOA",
343
                                        GWEN_PATH_FLAGS_NAMEMUSTEXIST);
344
        if (nnn)
345
          val=AB_ImExporterYN__ReadValue(ie, nnn, 343);
346

    
347
        if (val) {
348
          AB_BALANCE *bal;
349

    
350
          AB_Value_SetCurrency(val, AB_ImExporterAccountInfo_GetCurrency(ai));
351
          bal=AB_Balance_new();
352
          AB_Balance_SetType(bal, AB_Balance_TypeBooked);
353
          AB_Balance_SetDate(bal, dt);
354
          AB_Balance_SetValue(bal, val);
355
          AB_ImExporterAccountInfo_AddBalance(ai, bal);
356
        }
357
        AB_Value_free(val);
358
        GWEN_Date_free(dt);
359
      }
360
    }
361

    
362
    n=GWEN_XMLNode_FindNextTag(n, "SG4", 0, 0);
363
  }
364

    
365
  return 0;
366
}
367

    
368

    
369

    
370
int AB_ImExporterYN_Import(AB_IMEXPORTER *ie,
371
                           AB_IMEXPORTER_CONTEXT *ctx,
372
                           GWEN_SYNCIO *sio,
373
                           GWEN_DB_NODE *params){
374
  AB_IMEXPORTER_YELLOWNET *ieh;
375
  //GWEN_DB_NODE *dbSubParams;
376
  GWEN_XMLNODE *doc;
377
  GWEN_XMLNODE *node;
378
  int rv;
379
  GWEN_XML_CONTEXT *ctxml;
380

    
381
  assert(ie);
382
  ieh=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AB_IMEXPORTER_YELLOWNET, ie);
383
  assert(ieh);
384

    
385
//  dbSubParams=GWEN_DB_GetGroup(params, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
386
//                               "params");
387

    
388
  doc=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "root");
389
  ctxml=GWEN_XmlCtxStore_new(doc, GWEN_XML_FLAGS_HANDLE_HEADERS);
390
  rv=GWEN_XMLContext_ReadFromIo(ctxml, sio);
391
  GWEN_XmlCtx_free(ctxml);
392
  if (rv) {
393
    DBG_ERROR(AQBANKING_LOGDOMAIN,
394
              "Could not parse XML stream (%d)", rv);
395
    GWEN_XMLNode_free(doc);
396
    return GWEN_ERROR_BAD_DATA;
397
  }
398

    
399
  node=GWEN_XMLNode_FindFirstTag(doc, "IC", 0, 0);
400
  if (node==NULL) {
401
    DBG_ERROR(AQBANKING_LOGDOMAIN, "Document does not contain element \"IC\"");
402
    GWEN_XMLNode_Dump(doc, 2);
403
    GWEN_XMLNode_free(doc);
404
    return GWEN_ERROR_BAD_DATA;
405
  }
406
  node=GWEN_XMLNode_FindFirstTag(node, "KONAUS", 0, 0);
407
  while(node) {
408
    AB_IMEXPORTER_ACCOUNTINFO *ai;
409

    
410
    ai=AB_ImExporterYN__ReadAccountInfo(ie, ctx, node);
411
    assert(ai);
412

    
413
    rv=AB_ImExporterYN__ReadAccountStatus(ie, ai, node);
414
    if (rv==0)
415
      rv=AB_ImExporterYN__ReadTransactions(ie, ai, node);
416
    if (rv) {
417
      AB_ImExporterAccountInfo_free(ai);
418
      GWEN_XMLNode_free(doc);
419
      return rv;
420
    }
421

    
422
    AB_ImExporterContext_AddAccountInfo(ctx, ai);
423
    node=GWEN_XMLNode_FindNextTag(node, "KONAUS", 0, 0);
424
  }
425

    
426
  GWEN_XMLNode_free(doc);
427

    
428
  return 0;
429
}
430

    
431

    
432

    
433
int AB_ImExporterYN_CheckFile(AB_IMEXPORTER *ie, const char *fname){
434
  AB_IMEXPORTER_YELLOWNET *ieh;
435
  GWEN_SYNCIO *sio;
436
  int rv;
437
  uint8_t tbuf[256];
438

    
439
  assert(ie);
440
  assert(fname);
441

    
442
  assert(ie);
443
  ieh=GWEN_INHERIT_GETDATA(AB_IMEXPORTER, AB_IMEXPORTER_YELLOWNET, ie);
444
  assert(ieh);
445

    
446
  sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
447
  GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
448
  rv=GWEN_SyncIo_Connect(sio);
449
  if (rv<0) {
450
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
451
    GWEN_SyncIo_free(sio);
452
    return rv;
453
  }
454

    
455
  rv=GWEN_SyncIo_Read(sio, tbuf, sizeof(tbuf)-1);
456
  if (rv<1) {
457
    DBG_INFO(GWEN_LOGDOMAIN,
458
             "File \"%s\" is not supported by this plugin",
459
             fname);
460
    GWEN_SyncIo_Disconnect(sio);
461
    GWEN_SyncIo_free(sio);
462
    return GWEN_ERROR_BAD_DATA;
463
  }
464
  tbuf[rv-1]=0;
465
  if (-1!=GWEN_Text_ComparePattern((const char*)tbuf, "*<?xml*", 0) &&
466
      -1!=GWEN_Text_ComparePattern((const char*)tbuf, "*<KONAUS>*", 0)) {
467
    /* match */
468
    DBG_INFO(GWEN_LOGDOMAIN,
469
             "File \"%s\" is supported by this plugin",
470
             fname);
471
    GWEN_SyncIo_Disconnect(sio);
472
    GWEN_SyncIo_free(sio);
473
    return 0;
474
  }
475
  GWEN_SyncIo_Disconnect(sio);
476
  GWEN_SyncIo_free(sio);
477
  return GWEN_ERROR_BAD_DATA;
478
}
479

    
480

    
481