Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / parsers / swift / swift535.c @ 5bc3f3e7

History | View | Annotate | Download (11.6 KB)

1
/***************************************************************************
2
 begin       : Fri Apr 02 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 "swift535_p.h"
15
#include "i18n_l.h"
16

    
17
/* #include <aqhbci/aqhbci.h> */
18
#include <aqbanking/error.h>
19
#include <aqbanking/imexporter_be.h>
20

    
21
#include <gwenhywfar/text.h>
22
#include <gwenhywfar/debug.h>
23
#include <gwenhywfar/gwentime.h>
24
#include <gwenhywfar/gui.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <ctype.h>
28
#include <assert.h>
29

    
30

    
31

    
32
/* #define ENABLE_FULL_SEPA_LOG */
33

    
34

    
35
#define CENTURY_CUTOFF_YEAR 79
36

    
37

    
38

    
39
static void _iso8859_1ToUtf8(const char *p, int size, GWEN_BUFFER *buf) {
40
  while(*p) {
41
    unsigned int c;
42

    
43
    if (!size)
44
      break;
45

    
46
    c=(unsigned char)(*(p++));
47
    if (c<32 || c==127)
48
      c=32;
49
    if (c & 0x80) {
50
      GWEN_Buffer_AppendByte(buf, 0xc0 | c>>6);
51
      c &= ~0x40;
52
    }
53
    GWEN_Buffer_AppendByte(buf, c);
54
    if (size!=-1)
55
      size--;
56
  } /* while */
57
}
58

    
59

    
60

    
61
int AHB_SWIFT__SetCharValue535(GWEN_DB_NODE *db,
62
                               uint32_t flags,
63
                               const char *name,
64
                               const char *s) {
65
  GWEN_BUFFER *vbuf;
66
  int rv;
67

    
68
  vbuf=GWEN_Buffer_new(0, strlen(s)+32, 0, 1);
69
  _iso8859_1ToUtf8(s, -1, vbuf);
70
  rv=GWEN_DB_SetCharValue(db, flags, name, GWEN_Buffer_GetStart(vbuf));
71
  GWEN_Buffer_free(vbuf);
72
  return rv;
73
}
74

    
75

    
76

    
77
int AHB_SWIFT535_Parse_97A(const AHB_SWIFT_TAG *tg,
78
                           uint32_t flags,
79
                           GWEN_DB_NODE *data,
80
                           GWEN_DB_NODE *cfg){
81
  const char *p;
82
  const char *p2;
83

    
84
  p=AHB_SWIFT_Tag_GetData(tg);
85
  assert(p);
86

    
87
  while(*p && *p==32)
88
    p++;
89
  if (*p==0) {
90
    DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 97A is empty");
91
    return 0;
92
  }
93

    
94
  p2=strchr(p, '/');
95
  if (p2) {
96
    char *s;
97

    
98
    /* "BLZ/Konto" */
99
    s=(char*)GWEN_Memory_malloc(p2-p+1);
100
    memmove(s, p, p2-p+1);
101
    s[p2-p]=0;
102
    AHB_SWIFT__SetCharValue535(data,
103
                            GWEN_DB_FLAGS_OVERWRITE_VARS,
104
                            "localBankCode", s);
105
    GWEN_Memory_dealloc(s);
106
    p=p2+1;
107
  }
108

    
109
  while(*p && *p==32)
110
    p++;
111

    
112
  if (*p) {
113
    p2=p;
114
    while(*p2 && isdigit(*p2))
115
      p2++;
116
    if (p2==p) {
117
      DBG_INFO(AQBANKING_LOGDOMAIN,
118
               "LocalAccountNumber starts with nondigits (%s)", p);
119
      AHB_SWIFT__SetCharValue535(data,
120
                              GWEN_DB_FLAGS_OVERWRITE_VARS,
121
                              "localAccountNumber", p);
122
    }
123
    else {
124
      char *s;
125

    
126
      s=(char*)GWEN_Memory_malloc(p2-p+1);
127
      memmove(s, p, p2-p+1);
128
      s[p2-p]=0;
129
      AHB_SWIFT__SetCharValue535(data,
130
                              GWEN_DB_FLAGS_OVERWRITE_VARS,
131
                              "localAccountNumber", s);
132
      GWEN_Memory_dealloc(s);
133
    }
134
  }
135
  return 0;
136
}
137

    
138

    
139
// get names / IDs of security
140
int AHB_SWIFT535_Parse_35B(const AHB_SWIFT_TAG *tg,
141
                          uint32_t flags,
142
                          GWEN_DB_NODE *data,
143
                          GWEN_DB_NODE *cfg){
144
  char *p, *s, *ss;
145
  int gotIsin=0;
146

    
147
  p=(char *)AHB_SWIFT_Tag_GetData(tg);
148
  assert(p);
149

    
150
  while(*p && *p==32)
151
    p++;
152
  if (*p==0) {
153
    DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 35B is empty");
154
    return 0;
155
  }
156

    
157
  // get ISIN
158
  if (strncasecmp(p, "ISIN ", 5)==0) {
159
    p+=5;
160
    s=(char*)GWEN_Memory_malloc(1024);
161
    if (sscanf(p, " %s ", s)!=1) {
162
      DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 35B: Cannot read ISIN");
163
      GWEN_Memory_dealloc(s);
164
      return 0;
165
    }
166
    p+=strlen(s);
167
    AHB_SWIFT__SetCharValue535(data, flags, "nameSpace", "ISIN");
168
    AHB_SWIFT__SetCharValue535(data, flags, "uniqueId", s);
169
    GWEN_Memory_dealloc(s);
170
    gotIsin=1;
171
  }
172

    
173
  // get WKN
174
  while(*p && *p<=32) p++;
175

    
176
  if (strncasecmp(p, "/DE/", 4)==0) {
177
    p+=4;
178
    s=(char*)GWEN_Memory_malloc(1024);
179
    if (sscanf(p, "%s", s)!=1) {
180
      DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 35B: Cannot read WKN");
181
      GWEN_Memory_dealloc(s);
182
      return 0;
183
    }
184
    p+=strlen(s);
185
    if (!gotIsin) {
186
      AHB_SWIFT__SetCharValue535(data, flags, "nameSpace", "WKN");
187
      AHB_SWIFT__SetCharValue535(data, flags, "uniqueId", s);
188
    }
189
    GWEN_Memory_dealloc(s);
190
  }
191

    
192
  // get security name
193
  while(*p && *p<=32) p++;
194

    
195
  s=(char*)GWEN_Memory_malloc(1024);
196
  ss=s;
197
  while(*p) {
198
    if(*p>=32) *ss++ = *p;
199
    p++;
200
  }
201
  *ss=0;
202

    
203
  AHB_SWIFT__SetCharValue535(data, flags, "name", s);
204
  GWEN_Memory_dealloc(s);
205

    
206
  return 0;
207
}
208

    
209

    
210
// get price of security
211
int AHB_SWIFT535_Parse_90B(const AHB_SWIFT_TAG *tg,
212
                          uint32_t flags,
213
                          GWEN_DB_NODE *data,
214
                          GWEN_DB_NODE *cfg){
215
  char *p, *s;
216

    
217
  p=(char *)AHB_SWIFT_Tag_GetData(tg);
218
  assert(p);
219

    
220
  while(*p && *p==32)
221
    p++;
222
  if (*p==0) {
223
    DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 90B is empty");
224
    return 0;
225
  }
226

    
227
  // get price
228
  if (strncasecmp(p, ":MRKT//ACTU/", 12)==0) {
229
    p+=12;
230
    s=(char*)GWEN_Memory_malloc(1024);
231
    if (sscanf(p, " %3s ", s)!=1) {
232
      DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 90B: Cannot read currency");
233
      GWEN_Memory_dealloc(s);
234
      return 0;
235
    }
236
    p+=strlen(s);
237
    AHB_SWIFT__SetCharValue535(data, flags, "unitCurrency", s);
238

    
239
    if (sscanf(p, " %s ", s)!=1) {
240
      DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 90B: Cannot read price");
241
      GWEN_Memory_dealloc(s);
242
      return 0;
243
    }
244
    /*p+=strlen(s); */
245
    AHB_SWIFT__SetCharValue535(data, flags, "unitPrice", s);
246

    
247
    GWEN_Memory_dealloc(s);
248
  }
249

    
250
  return 0;
251
}
252

    
253

    
254
// get date of security price
255
int AHB_SWIFT535_Parse_98A(const AHB_SWIFT_TAG *tg,
256
                          uint32_t flags,
257
                          GWEN_DB_NODE *data,
258
                          GWEN_DB_NODE *cfg){
259
  char *p;
260
  int year, month, day;
261
  GWEN_DATE *dt;
262

    
263
  p=(char *)AHB_SWIFT_Tag_GetData(tg);
264
  assert(p);
265

    
266
  while(*p && *p==32)
267
    p++;
268
  if (*p==0) {
269
    DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 98A is empty");
270
    return 0;
271
  }
272

    
273
  // get date
274
  if (strncasecmp(p, ":PRIC//", 7)==0) {
275
    p+=7;
276
    if (sscanf(p, "%4d%2d%2d", &year, &month, &day)!=3) {
277
      DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 98A: Cannot read date");
278
      return 0;
279
    }
280
    dt=GWEN_Date_fromGregorian(year, month, day);
281
    assert(dt);
282

    
283
    GWEN_DB_SetCharValue(data, GWEN_DB_FLAGS_DEFAULT, "unitPriceDate", GWEN_Date_GetString(dt));
284
    GWEN_Date_free(dt);
285
  }
286

    
287
  return 0;
288
}
289

    
290

    
291
// get units of security
292
int AHB_SWIFT535_Parse_93B(const AHB_SWIFT_TAG *tg,
293
                          uint32_t flags,
294
                          GWEN_DB_NODE *data,
295
                          GWEN_DB_NODE *cfg){
296
  char *p;
297

    
298
  p=(char *)AHB_SWIFT_Tag_GetData(tg);
299
  assert(p);
300

    
301
  while(*p && *p==32)
302
    p++;
303
  if (*p==0) {
304
    DBG_WARN(AQBANKING_LOGDOMAIN, "Tag 93B is empty");
305
    return 0;
306
  }
307

    
308
  // get units
309
  if (strncasecmp(p, ":AGGR//UNIT/", 12)==0) {
310
    p+=12;
311
    AHB_SWIFT__SetCharValue535(data, flags, "units", p);
312
  }
313

    
314
  return 0;
315
}
316

    
317

    
318

    
319
/* Import SWIFT MT535 data.
320
   @param tl input: list of tags. Tags are lines in a SWIFT data block (block 4). A tag has an
321
          id and content. See the AHB_SWIFT_Tag_new function for more information.
322
 */
323
int AHB_SWIFT535_Import(AHB_SWIFT_TAG_LIST *tl,
324
                        GWEN_DB_NODE *data,
325
                        GWEN_DB_NODE *cfg,
326
                        uint32_t flags) {
327
  AHB_SWIFT_TAG *tg;
328
  GWEN_DB_NODE *dbTemplate=NULL;
329
  GWEN_DB_NODE *dbSecurity=NULL;
330
  uint32_t progressId;
331
  int docLvl;
332

    
333
  dbTemplate=GWEN_DB_Group_new("template");
334

    
335
  progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
336
                                    GWEN_GUI_PROGRESS_ALLOW_EMBED |
337
                                    GWEN_GUI_PROGRESS_SHOW_PROGRESS |
338
                                    GWEN_GUI_PROGRESS_SHOW_ABORT,
339
                                    I18N("Importing SWIFT tags..."),
340
                                    NULL,
341
                                    AHB_SWIFT_Tag_List_GetCount(tl),
342
                                    0);
343

    
344

    
345
  docLvl=AHB_SWIFT535_LEVEL_TOP;
346

    
347
  tg=AHB_SWIFT_Tag_List_First(tl);
348
  while(tg) {
349
    const char *id;
350
    const char *da;
351

    
352
    id=AHB_SWIFT_Tag_GetId(tg);
353
    da=AHB_SWIFT_Tag_GetData(tg);
354
    assert(id);
355
    assert(da);
356

    
357
    switch(docLvl) {
358
    case AHB_SWIFT535_LEVEL_TOP:
359
      if (strcasecmp(id, "16R")==0) {
360
        if (strcasecmp(da, "GENL")==0)
361
          docLvl=AHB_SWIFT535_LEVEL_GENL;
362
        //        else if (strcasecmp(da, "SUBSAFE")==0)
363
        //          docLvl=AHB_SWIFT535_LEVEL_SUBSAFE;
364
        else if (strcasecmp(da, "FIN")==0) {
365
          docLvl=AHB_SWIFT535_LEVEL_FIN;
366
          dbSecurity=GWEN_DB_GetGroup(data, GWEN_PATH_FLAGS_CREATE_GROUP, "security");
367
        }
368
        else if (strcasecmp(da, "ADDINFO")==0)
369
          docLvl=AHB_SWIFT535_LEVEL_ADDINFO;
370
        else
371
          DBG_INFO(AQBANKING_LOGDOMAIN, "TOP: Ignoring tag :%s:%s", id, da);
372
      }
373
      break;
374

    
375
    case AHB_SWIFT535_LEVEL_GENL:
376
      if (strcasecmp(id, "16S")==0 && strcasecmp(da, "GENL")==0)
377
        docLvl=AHB_SWIFT535_LEVEL_TOP;
378

    
379
      else if (strcasecmp(id, "97A")==0) { /* LocalAccount */
380
          if (AHB_SWIFT535_Parse_97A(tg, flags, data, cfg)) {
381
            DBG_WARN(AQBANKING_LOGDOMAIN, "Error in tag %s", id);
382
            GWEN_Gui_ProgressEnd(progressId);
383
            return -1;
384
          }
385
      }
386
      
387
      else
388
        DBG_INFO(AQBANKING_LOGDOMAIN, "GENL: Ignoring tag :%s:%s", id, da);
389
      break;
390

    
391
    case AHB_SWIFT535_LEVEL_SUBSAFE:
392
      if (strcasecmp(id, "16S")==0 && strcasecmp(da, "SUBSAFE")==0)
393
        docLvl=AHB_SWIFT535_LEVEL_TOP;
394
      else
395
        DBG_INFO(AQBANKING_LOGDOMAIN, "SUBSAFE: Ignoring tag :%s:%s", id, da);
396
      break;
397

    
398
    case AHB_SWIFT535_LEVEL_FIN:
399
      if (strcasecmp(id, "16S")==0 && strcasecmp(da, "FIN")==0)
400
        //        docLvl=AHB_SWIFT535_LEVEL_SUBSAFE;
401
        docLvl=AHB_SWIFT535_LEVEL_TOP;
402

    
403
      else if (strcasecmp(id, "16R")==0 && strcasecmp(da, "SUBBAL")==0)
404
          docLvl=AHB_SWIFT535_LEVEL_SUBBAL;
405

    
406
      else if (strcasecmp(id, "35B")==0) { /* name of security */
407
          if (AHB_SWIFT535_Parse_35B(tg, flags, dbSecurity, cfg)) {
408
            DBG_WARN(AQBANKING_LOGDOMAIN, "Error in tag %s", id);
409
            GWEN_Gui_ProgressEnd(progressId);
410
            return -1;
411
          }
412
      }
413

    
414
      else if (strcasecmp(id, "90B")==0) { /* price of security */
415
          if (AHB_SWIFT535_Parse_90B(tg, flags, dbSecurity, cfg)) {
416
            DBG_WARN(AQBANKING_LOGDOMAIN, "Error in tag %s", id);
417
            GWEN_Gui_ProgressEnd(progressId);
418
            return -1;
419
          }
420
      }
421

    
422
      else if (strcasecmp(id, "98A")==0) { /* date of security price*/
423
          if (AHB_SWIFT535_Parse_98A(tg, flags, dbSecurity, cfg)) {
424
            DBG_WARN(AQBANKING_LOGDOMAIN, "Error in tag %s", id);
425
            GWEN_Gui_ProgressEnd(progressId);
426
            return -1;
427
          }
428
      }
429

    
430
      else if (strcasecmp(id, "93B")==0) { /* units of security */
431
          if (AHB_SWIFT535_Parse_93B(tg, flags, dbSecurity, cfg)) {
432
            DBG_WARN(AQBANKING_LOGDOMAIN, "Error in tag %s", id);
433
            GWEN_Gui_ProgressEnd(progressId);
434
            return -1;
435
          }
436
      }
437

    
438
      else
439
        DBG_INFO(AQBANKING_LOGDOMAIN, "FIN: Ignoring tag :%s:%s", id, da);
440
      break;
441

    
442
    case AHB_SWIFT535_LEVEL_SUBBAL:
443
      if (strcasecmp(id, "16S")==0 && strcasecmp(da, "SUBBAL")==0)
444
        docLvl=AHB_SWIFT535_LEVEL_FIN;
445
      else
446
        DBG_INFO(AQBANKING_LOGDOMAIN, "SUBBAL: Ignoring tag :%s:%s", id, da);
447
      break;
448

    
449
    case AHB_SWIFT535_LEVEL_ADDINFO:
450
      if (strcasecmp(id, "16S")==0 && strcasecmp(da, "ADDINFO")==0)
451
        docLvl=AHB_SWIFT535_LEVEL_TOP;
452
      else
453
        DBG_INFO(AQBANKING_LOGDOMAIN, "ADDINFO: Ignoring tag :%s:%s", id, da);
454
      break;
455

    
456
    }
457

    
458
    if (GWEN_Gui_ProgressAdvance(progressId, GWEN_GUI_PROGRESS_ONE)==
459
        GWEN_ERROR_USER_ABORTED) {
460
      GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
461
                           I18N("Aborted by user"));
462
      GWEN_Gui_ProgressEnd(progressId);
463
      GWEN_DB_Group_free(dbTemplate);
464
      return GWEN_ERROR_USER_ABORTED;
465
    }
466

    
467
    tg=AHB_SWIFT_Tag_List_Next(tg);
468
  } /* while */
469

    
470
  if (docLvl!=AHB_SWIFT535_LEVEL_TOP)
471
    DBG_WARN(AQBANKING_LOGDOMAIN, "Illegal document structure");
472
  GWEN_DB_Group_free(dbTemplate);
473
  GWEN_Gui_ProgressEnd(progressId);
474

    
475
  return 0;
476
}