Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / backends / aqhbci / ajobs / jobgetbalance.c @ f4a16f5b

History | View | Annotate | Download (14.1 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

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

    
15

    
16
#include "jobgetbalance_p.h"
17
#include "aqhbci_l.h"
18
#include "accountjob_l.h"
19
#include "job_l.h"
20
#include "user_l.h"
21

    
22
#include <gwenhywfar/debug.h>
23
#include <gwenhywfar/misc.h>
24
#include <gwenhywfar/inherit.h>
25
#include <gwenhywfar/dbio.h>
26
#include <gwenhywfar/syncio_memory.h>
27

    
28
#include <stdlib.h>
29
#include <assert.h>
30
#include <string.h>
31

    
32

    
33

    
34
GWEN_INHERIT(AH_JOB, AH_JOB_GETBALANCE);
35

    
36

    
37

    
38

    
39
/* --------------------------------------------------------------- FUNCTION */
40
AH_JOB *AH_Job_GetBalance_new(AB_PROVIDER *pro, AB_USER *u, AB_ACCOUNT *account) {
41
  AH_JOB *j;
42
  AH_JOB_GETBALANCE *aj;
43
  GWEN_DB_NODE *dbArgs;
44
  int useCreditCardJob=0;
45
  int useInvestmentJob=0;
46
  GWEN_DB_NODE *updgroup;
47

    
48
  //Check if we should use DKKKS
49
  updgroup=AH_User_GetUpdForAccount(u, account);
50
  if (updgroup) {
51
    GWEN_DB_NODE *n;
52

    
53
    n=GWEN_DB_GetFirstGroup(updgroup);
54
    while(n) {
55
      if (strcasecmp(GWEN_DB_GetCharValue(n, "job", 0, ""), "DKKKS")==0) {
56
        useCreditCardJob = 1;
57
        break;
58
      }
59

    
60
      if (strcasecmp(GWEN_DB_GetCharValue(n, "job", 0, ""), "HKWPD")==0) {
61
        useInvestmentJob = 1;
62
        break;
63
      }
64
      n=GWEN_DB_GetNextGroup(n);
65
    } /* while */
66
  } /* if updgroup for the given account found */
67

    
68
  if(useCreditCardJob)
69
    j=AH_AccountJob_new("JobGetBalanceCreditCard", pro, u, account);
70
  else if(useInvestmentJob)
71
    j=AH_AccountJob_new("JobGetBalanceInvestment", pro, u, account);
72
  else
73
    j=AH_AccountJob_new("JobGetBalance", pro, u, account);
74
  if (!j)
75
    return 0;
76

    
77
  GWEN_NEW_OBJECT(AH_JOB_GETBALANCE, aj);
78
  GWEN_INHERIT_SETDATA(AH_JOB, AH_JOB_GETBALANCE, j, aj, AH_Job_GetBalance_FreeData);
79

    
80
  AH_Job_SetSupportedCommand(j, AB_Transaction_CommandGetBalance);
81

    
82
  /* overwrite some virtual functions */
83
  if(useInvestmentJob)
84
    AH_Job_SetProcessFn(j, AH_Job_GetBalanceInvestment_Process);
85
  else
86
    AH_Job_SetProcessFn(j, AH_Job_GetBalance_Process);
87
  AH_Job_SetGetLimitsFn(j, AH_Job_GetLimits_EmptyLimits);
88
  AH_Job_SetHandleCommandFn(j, AH_Job_HandleCommand_Accept);
89
  AH_Job_SetHandleResultsFn(j, AH_Job_HandleResults_Empty);
90

    
91
  /* set some known arguments */
92
  dbArgs=AH_Job_GetArguments(j);
93
  assert(dbArgs);
94
  if (useCreditCardJob || useInvestmentJob)
95
    GWEN_DB_SetCharValue(dbArgs, GWEN_DB_FLAGS_DEFAULT, "accountNumber", AB_Account_GetAccountNumber(account));
96
  else
97
    GWEN_DB_SetCharValue(dbArgs, GWEN_DB_FLAGS_DEFAULT, "allAccounts", "N");
98

    
99
  return j;
100
}
101

    
102

    
103

    
104
/* --------------------------------------------------------------- FUNCTION */
105
void GWENHYWFAR_CB AH_Job_GetBalance_FreeData(void *bp, void *p){
106
  AH_JOB_GETBALANCE *aj;
107

    
108
  aj=(AH_JOB_GETBALANCE*)p;
109
  GWEN_FREE_OBJECT(aj);
110
}
111

    
112

    
113

    
114
/* --------------------------------------------------------------- FUNCTION */
115
AB_BALANCE *AH_Job_GetBalance__ReadBalance(GWEN_DB_NODE *dbT) {
116
  AB_VALUE *v;
117
  const char *p;
118
  AB_BALANCE *bal;
119
  int isCredit=0;
120

    
121
  bal=AB_Balance_new();
122

    
123
  /* get isCredit */
124
  p=GWEN_DB_GetCharValue(dbT, "debitMark", 0, 0);
125
  if (p) {
126
    if (strcasecmp(p, "D")==0 ||
127
        strcasecmp(p, "RC")==0) {
128
      isCredit=0;
129
    }
130
    else if (strcasecmp(p, "C")==0 ||
131
             strcasecmp(p, "RD")==0)
132
      isCredit=1;
133
    else {
134
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad debit mark \"%s\"", p);
135
      AB_Balance_free(bal);
136
      return NULL;
137
    }
138
  }
139

    
140
  /* read date */
141
  p=GWEN_DB_GetCharValue(dbT, "date", 0, 0);
142
  if (p) {
143
    GWEN_DATE *dt;
144

    
145
    dt=GWEN_Date_fromStringWithTemplate(p, "YYYYMMDD");
146
    if (dt) {
147
      AB_Balance_SetDate(bal, dt);
148
      GWEN_Date_free(dt);
149
    }
150
    else {
151
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad date \"%s\"", p);
152
      AB_Balance_free(bal);
153
      return NULL;
154
    }
155
  }
156
  else {
157
    GWEN_DATE *dt;
158

    
159
    DBG_WARN(AQHBCI_LOGDOMAIN, "No date, using current date");
160
    dt=GWEN_Date_CurrentDate();
161
    assert(dt);
162
    AB_Balance_SetDate(bal, dt);
163
    GWEN_Date_free(dt);
164
  }
165

    
166
  /* get value */
167
  v=AB_Value_fromDb(dbT);
168
  if (!v) {
169
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Error parsing value from DB");
170
    AB_Balance_free(bal);
171
    return NULL;
172
  }
173
  else {
174
    if (!isCredit)
175
      AB_Value_Negate(v);
176

    
177
    AB_Balance_SetValue(bal, v);
178
    AB_Value_free(v);
179
  }
180

    
181
  return bal;
182
}
183

    
184

    
185

    
186
/* --------------------------------------------------------------- FUNCTION */
187
int AH_Job_GetBalance__ReadSecurities(AH_JOB *j,
188
                                      AB_IMEXPORTER_CONTEXT *ctx,
189
                                      const char *docType,
190
                                      int noted,
191
                                      GWEN_BUFFER *buf){
192
  GWEN_DBIO *dbio;
193
  GWEN_SYNCIO *sio;
194
  int rv;
195
  GWEN_DB_NODE *db;
196
  GWEN_DB_NODE *dbSecurity;
197
  GWEN_DB_NODE *dbParams;
198
  AB_ACCOUNT *a;
199
  AB_USER *u;
200
  uint32_t progressId;
201
  uint64_t cnt=0;
202

    
203
  
204
  a=AH_AccountJob_GetAccount(j);
205
  assert(a);
206
  u=AH_Job_GetUser(j);
207
  assert(u);
208

    
209
  dbio=GWEN_DBIO_GetPlugin("swift");
210
  if (!dbio) {
211
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Plugin SWIFT is not found");
212
    GWEN_Gui_ProgressLog(0,
213
                         GWEN_LoggerLevel_Error,
214
                         I18N("Plugin \"SWIFT\" not found."));
215
    return AB_ERROR_PLUGIN_MISSING;
216
  }
217

    
218
  GWEN_Buffer_Rewind(buf);
219
  sio=GWEN_SyncIo_Memory_new(buf, 0);
220

    
221

    
222
  db=GWEN_DB_Group_new("transactions");
223
  dbParams=GWEN_DB_Group_new("params");
224
  GWEN_DB_SetCharValue(dbParams, GWEN_DB_FLAGS_OVERWRITE_VARS,
225
                       "type", docType);
226
  if (AH_User_GetFlags(u) & AH_USER_FLAGS_KEEP_MULTIPLE_BLANKS)
227
    GWEN_DB_SetIntValue(dbParams, GWEN_DB_FLAGS_OVERWRITE_VARS,
228
                        "keepMultipleBlanks", 1);
229
  else
230
    GWEN_DB_SetIntValue(dbParams, GWEN_DB_FLAGS_OVERWRITE_VARS,
231
                        "keepMultipleBlanks", 0);
232

    
233
  rv=GWEN_DBIO_Import(dbio, sio,
234
                      db, dbParams,
235
                      GWEN_PATH_FLAGS_CREATE_GROUP);
236
  if (rv<0) {
237
    DBG_ERROR(AQHBCI_LOGDOMAIN,
238
              "Error parsing SWIFT %s (%d)",
239
              docType, rv);
240
    GWEN_DB_Group_free(dbParams);
241
    GWEN_DB_Group_free(db);
242
    GWEN_SyncIo_free(sio);
243
    GWEN_DBIO_free(dbio);
244
    return rv;
245
  }
246
  GWEN_DB_Group_free(dbParams);
247
  GWEN_SyncIo_free(sio);
248
  GWEN_DBIO_free(dbio);
249

    
250
  /* first count the securities */
251
  dbSecurity=GWEN_DB_FindFirstGroup(db, "security");
252
  while(dbSecurity) {
253
    cnt++;
254
    dbSecurity=GWEN_DB_FindNextGroup(dbSecurity, "security");
255
  } /* while */
256

    
257
  progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
258
                                    GWEN_GUI_PROGRESS_ALLOW_EMBED |
259
                                    GWEN_GUI_PROGRESS_SHOW_PROGRESS |
260
                                    GWEN_GUI_PROGRESS_SHOW_ABORT,
261
                                    I18N("Importing transactions..."),
262
                                    NULL,
263
                                    cnt,
264
                                    0);
265

    
266
  /* add security to list */
267
  dbSecurity=GWEN_DB_FindFirstGroup(db, "security");
268
  while(dbSecurity) {
269
    AB_SECURITY *asec;
270
    AB_VALUE *aval;
271
    GWEN_TIME *gt;
272
    const char *p;
273

    
274
    asec=AB_Security_new();
275

    
276
    p=GWEN_DB_GetCharValue(dbSecurity, "name", 0, NULL);
277
    if (p) {
278
      AB_Security_SetName(asec, p);
279
    }
280

    
281
    p=GWEN_DB_GetCharValue(dbSecurity, "nameSpace", 0, NULL);
282
    if (p) {
283
      AB_Security_SetNameSpace(asec, p);
284
    }
285

    
286
    p=GWEN_DB_GetCharValue(dbSecurity, "uniqueId", 0, NULL);
287
    if (p) {
288
      AB_Security_SetUniqueId(asec, p);
289
    }
290

    
291
    p=GWEN_DB_GetCharValue(dbSecurity, "units", 0, NULL);
292
    if (p) {
293
      aval=AB_Value_fromString(p);
294
      AB_Security_SetUnits(asec, aval);
295
      AB_Value_free(aval);
296
    }
297

    
298
    p=GWEN_DB_GetCharValue(dbSecurity, "unitPrice", 0, NULL);
299
    if (p) {
300
      aval=AB_Value_fromString(p);
301
      p=GWEN_DB_GetCharValue(dbSecurity, "unitCurrency", 0, NULL);
302
      if (p) AB_Value_SetCurrency(aval, p);
303
      AB_Security_SetUnitPriceValue(asec, aval);
304
      AB_Value_free(aval);
305
    }
306

    
307
    gt=GWEN_Time_fromDb(GWEN_DB_GetGroup(dbSecurity,
308
                                         GWEN_DB_FLAGS_DEFAULT,
309
                                         "unitPriceDate"));
310
    if (gt) {
311
      AB_Security_SetUnitPriceDate(asec, gt);
312
    }
313
    
314
    AB_ImExporterContext_AddSecurity(ctx, asec);
315

    
316
    GWEN_Time_free(gt);
317

    
318
    dbSecurity=GWEN_DB_FindNextGroup(dbSecurity, "security");
319
  } /* while */
320

    
321
  GWEN_Gui_ProgressEnd(progressId);
322

    
323
  GWEN_DB_Group_free(db);
324
  return 0;
325
}
326

    
327

    
328
/* --------------------------------------------------------------- FUNCTION */
329
int AH_Job_GetBalance_Process(AH_JOB *j, AB_IMEXPORTER_CONTEXT *ctx){
330
  AH_JOB_GETBALANCE *aj;
331
  GWEN_DB_NODE *dbResponses;
332
  GWEN_DB_NODE *dbCurr;
333
  int rv;
334

    
335
  DBG_INFO(AQHBCI_LOGDOMAIN, "Processing JobGetBalance");
336

    
337
  assert(j);
338
  aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_GETBALANCE, j);
339
  assert(aj);
340

    
341
  dbResponses=AH_Job_GetResponses(j);
342
  assert(dbResponses);
343
  
344
  /* search for "Balance" */
345
  dbCurr=GWEN_DB_GetFirstGroup(dbResponses);
346
  while(dbCurr) {
347
    GWEN_DB_NODE *dbBalance;
348

    
349
    rv=AH_Job_CheckEncryption(j, dbCurr);
350
    if (rv) {
351
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (encryption)");
352
      AH_Job_SetStatus(j, AH_JobStatusError);
353
      return rv;
354
    }
355
    rv=AH_Job_CheckSignature(j, dbCurr);
356
    if (rv) {
357
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (signature)");
358
      AH_Job_SetStatus(j, AH_JobStatusError);
359
      return rv;
360
    }
361

    
362
    dbBalance=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "data/balance");
363
    if (!dbBalance)
364
      dbBalance=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "data/balancecreditcard");
365
    if (dbBalance) {
366
      GWEN_DB_NODE *dbT;
367
      AB_ACCOUNT *a;
368
      AB_IMEXPORTER_ACCOUNTINFO *ai;
369

    
370
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Got a balance");
371
      if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug)
372
        GWEN_DB_Dump(dbBalance, 2);
373

    
374
      a=AH_AccountJob_GetAccount(j);
375
      assert(a);
376
      ai=AB_ImExporterContext_GetOrAddAccountInfo(ctx,
377
                                                  AB_Account_GetUniqueId(a),
378
                                                  AB_Account_GetIban(a),
379
                                                  AB_Account_GetBankCode(a),
380
                                                  AB_Account_GetAccountNumber(a),
381
                                                  AB_Account_GetAccountType(a));
382
      assert(ai);
383

    
384

    
385
      /* read booked balance */
386
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "booked");
387
      if (dbT) {
388
        AB_BALANCE *bal;
389

    
390
        bal=AH_Job_GetBalance__ReadBalance(dbT);
391
        if (bal) {
392
          AB_Balance_SetType(bal, AB_Balance_TypeBooked);
393
          AB_ImExporterAccountInfo_AddBalance(ai, bal);
394
        }
395
      }
396

    
397
      /* read noted balance */
398
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "noted");
399
      if (dbT) {
400
        AB_BALANCE *bal;
401

    
402
        bal=AH_Job_GetBalance__ReadBalance(dbT);
403
        if (bal) {
404
          AB_Balance_SetType(bal, AB_Balance_TypeNoted);
405
          AB_ImExporterAccountInfo_AddBalance(ai, bal);
406
        }
407
      }
408

    
409
#if 0
410
      /* read credit Line */
411
      dbT=GWEN_DB_GetGroup(dbBalance, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "creditLine");
412
      if (dbT) {
413
        AB_VALUE *v;
414

415
        v=AB_Value_fromDb(dbT);
416
        if (!v) {
417
          DBG_ERROR(AQHBCI_LOGDOMAIN, "Error parsing value from DB");
418
        }
419
        else {
420
          AB_AccountStatus_SetBankLine(acst, v);
421
        }
422
        AB_Value_free(v);
423
      }
424
#endif
425

    
426
      break; /* break loop, we found the balance */
427
    } /* if "Balance" */
428

    
429
    dbCurr=GWEN_DB_GetNextGroup(dbCurr);
430
  }
431

    
432
  return 0;
433
}
434

    
435

    
436

    
437
/* --------------------------------------------------------------- FUNCTION */
438
int AH_Job_GetBalanceInvestment_Process(AH_JOB *j, AB_IMEXPORTER_CONTEXT *ctx){
439
  AH_JOB_GETBALANCE *aj;
440
  GWEN_DB_NODE *dbResponses;
441
  GWEN_DB_NODE *dbCurr;
442
  GWEN_BUFFER *tbooked;
443
  AB_ACCOUNT *a;
444
  AB_IMEXPORTER_ACCOUNTINFO *ai;
445
  int rv;
446

    
447
  DBG_INFO(AQHBCI_LOGDOMAIN, "Processing JobGetBalance");
448

    
449
  assert(j);
450
  aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_GETBALANCE, j);
451
  assert(aj);
452

    
453
  dbResponses=AH_Job_GetResponses(j);
454
  assert(dbResponses);
455
  
456
  tbooked=GWEN_Buffer_new(0, 8192, 0, 1);
457

    
458
  /* search for "Balance" */
459
  dbCurr=GWEN_DB_GetFirstGroup(dbResponses);
460
  while(dbCurr) {
461
    GWEN_DB_NODE *dbBalance;
462

    
463
    //GWEN_DB_Dump(dbCurr, 8);
464

    
465
    rv=AH_Job_CheckEncryption(j, dbCurr);
466
    if (rv) {
467
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (encryption)");
468
      AH_Job_SetStatus(j, AH_JobStatusError);
469
      return rv;
470
    }
471
    rv=AH_Job_CheckSignature(j, dbCurr);
472
    if (rv) {
473
      DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (signature)");
474
      AH_Job_SetStatus(j, AH_JobStatusError);
475
      return rv;
476
    }
477

    
478
    dbBalance=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
479
                               "data/BalanceInvestment");
480

    
481
    if (dbBalance) {
482
      const void *p;
483
      unsigned int bs;
484

    
485
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Got a balance");
486
      if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug)
487
        GWEN_DB_Dump(dbBalance, 2);
488

    
489
      p=GWEN_DB_GetBinValue(dbBalance, "booked", 0, 0, 0, &bs);
490
      if (p && bs)
491
        GWEN_Buffer_AppendBytes(tbooked, p, bs);
492

    
493
      break; /* break loop, we found the balance */
494
    } /* if(dbBalance) */
495

    
496
    dbCurr=GWEN_DB_GetNextGroup(dbCurr);
497
  } /* while(dbCurr) */
498

    
499
  GWEN_Buffer_Rewind(tbooked);
500

    
501
  /* now the buffers contain data to be parsed by DBIOs */
502
  a=AH_AccountJob_GetAccount(j);
503
  assert(a);
504
  ai=AB_ImExporterContext_GetOrAddAccountInfo(ctx,
505
                                              AB_Account_GetUniqueId(a),
506
                                              AB_Account_GetIban(a),
507
                                              AB_Account_GetBankCode(a),
508
                                              AB_Account_GetAccountNumber(a),
509
                                              AB_Account_GetAccountType(a));
510
  assert(ai);
511

    
512
  /* read received securities */
513
  if (GWEN_Buffer_GetUsedBytes(tbooked)) {
514

    
515
    if (AH_Job_GetBalance__ReadSecurities(j, ctx, "mt535", 0, tbooked)){
516
      GWEN_Buffer_free(tbooked);
517
      DBG_INFO(AQHBCI_LOGDOMAIN, "Error parsing received securities");
518
      AH_Job_SetStatus(j, AH_JobStatusError);
519
      return -1;
520
    }
521
  }
522

    
523
  if (GWEN_Logger_GetLevel(AQHBCI_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) {
524
    GWEN_DB_NODE *gn;
525
    AB_SECURITY *stmp;
526

    
527
    DBG_INFO(AQHBCI_LOGDOMAIN, "*** Dumping securities *********************");
528
    stmp=AB_ImExporterContext_GetFirstSecurity(ctx);
529
    while (stmp) {
530
      DBG_INFO(AQHBCI_LOGDOMAIN, "*** --------------------------------------");
531
      gn=GWEN_DB_Group_new("security");
532
      AB_Security_toDb(stmp, gn);
533
      GWEN_DB_Dump(gn, 2);
534
      if (gn)
535
        GWEN_DB_Group_free(gn);
536
      stmp=AB_Security_List_Next(stmp);
537
    }
538
    AB_Security_free(stmp);
539

    
540
    DBG_INFO(AQHBCI_LOGDOMAIN, "*** End dumping securities *****************");
541
  }
542

    
543
  GWEN_Buffer_free(tbooked);
544
  return 0;
545
}
546

    
547

    
548