Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / aqbanking / banking_transaction.c @ 942309da

History | View | Annotate | Download (18.5 KB)

1
/***************************************************************************
2
 begin       : Thu Oct 04 2018
3
 copyright   : (C) 2018 by Martin Preuss
4
 email       : martin@libchipcard.de
5

6
 ***************************************************************************
7
 * This file is part of the project "AqBanking".                           *
8
 * Please see toplevel file COPYING of that project for license details.   *
9
 ***************************************************************************/
10

    
11
/* This file is included by banking.c */
12

    
13

    
14

    
15
int AB_Banking_CheckTransactionAgainstLimits_Purpose(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
16
  int maxn;
17
  int maxs;
18
  const char *purpose;
19

    
20
  /* check purpose */
21
  if (lim) {
22
    maxn=AB_TransactionLimits_GetMaxLinesPurpose(lim);
23
    maxs=AB_TransactionLimits_GetMaxLenPurpose(lim);
24
  }
25
  else {
26
    DBG_INFO(AQBANKING_LOGDOMAIN, "No transaction limits");
27
    maxn=0;
28
    maxs=0;
29
  }
30

    
31
  purpose=AB_Transaction_GetPurpose(t);
32
  if (purpose && *purpose) {
33
    GWEN_STRINGLIST *sl;
34

    
35
    sl=GWEN_StringList_fromString(purpose, "\n", 0);
36
    if (sl && GWEN_StringList_Count(sl)) {
37
      int n;
38
      GWEN_STRINGLISTENTRY *se;
39
      const char *p;
40

    
41
      n=0;
42
      se=GWEN_StringList_FirstEntry(sl);
43
      while(se) {
44
        p=GWEN_StringListEntry_Data(se);
45
        if (p && *p) {
46
          n++;
47
          if (maxn && n>maxn) {
48
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many purpose lines (%d>%d)", n, maxn);
49
            GWEN_Gui_ProgressLog2(0,
50
                                  GWEN_LoggerLevel_Error,
51
                                  I18N("Too many purpose lines (%d>%d)"),
52
                                  n, maxn);
53
            GWEN_StringList_free(sl);
54
            return GWEN_ERROR_INVALID;
55
          }
56
          else {
57
            int l;
58
            GWEN_BUFFER *tbuf;
59

    
60
            tbuf=GWEN_Buffer_new(0, maxs, 0, 1);
61
            AB_ImExporter_Utf8ToDta(p, -1, tbuf);
62
            GWEN_Text_CondenseBuffer(tbuf);
63
            l=GWEN_Buffer_GetUsedBytes(tbuf);
64
            if (maxs && l>maxs) {
65
              DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in purpose line %d (%d>%d)", n, l, maxs);
66
              GWEN_Gui_ProgressLog2(0,
67
                                    GWEN_LoggerLevel_Error,
68
                                    I18N("Too many chars in purpose line %d (%d>%d)"),
69
                                    n, l, maxs);
70
              GWEN_Buffer_free(tbuf);
71
              GWEN_StringList_free(sl);
72
              return GWEN_ERROR_INVALID;
73
            }
74
            GWEN_Buffer_free(tbuf);
75
          }
76
        }
77
        se=GWEN_StringListEntry_Next(se);
78
      } /* while */
79
      if (!n) {
80
        DBG_ERROR(AQBANKING_LOGDOMAIN, "No purpose lines");
81
        GWEN_StringList_free(sl);
82
        return GWEN_ERROR_INVALID;
83
      }
84
    }
85
    GWEN_StringList_free(sl);
86
  }
87
  return 0;
88
}
89

    
90

    
91

    
92
int AB_Banking_CheckTransactionAgainstLimits_Names(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
93
  int maxs;
94
  const char *s;
95

    
96
  /* check remote name */
97
  if (lim)
98
    maxs=AB_TransactionLimits_GetMaxLenRemoteName(lim);
99
  else
100
    maxs=0;
101

    
102
  s=AB_Transaction_GetRemoteName(t);
103
  if (s && *s) {
104
    int l;
105
    GWEN_BUFFER *tbuf;
106

    
107
    tbuf=GWEN_Buffer_new(0, 256, 0, 1);
108
    AB_ImExporter_Utf8ToDta(s, -1, tbuf);
109
    GWEN_Text_CondenseBuffer(tbuf);
110
    l=GWEN_Buffer_GetUsedBytes(tbuf);
111
    if (maxs>0 && l>maxs) {
112
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in remote name (%d>%d)", l, maxs);
113
      GWEN_Buffer_free(tbuf);
114
      return GWEN_ERROR_INVALID;
115
    }
116
    GWEN_Buffer_free(tbuf);
117
  }
118
  else {
119
    DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing remote name");
120
    return GWEN_ERROR_INVALID;
121
  }
122

    
123
  /* check local name */
124
  if (lim)
125
    maxs=AB_TransactionLimits_GetMaxLenLocalName(lim);
126
  else
127
    maxs=0;
128
  s=AB_Transaction_GetLocalName(t);
129
  if (s && *s) {
130
    int l;
131
    GWEN_BUFFER *tbuf;
132

    
133
    tbuf=GWEN_Buffer_new(0, 256, 0, 1);
134
    AB_ImExporter_Utf8ToDta(s, -1, tbuf);
135
    GWEN_Text_CondenseBuffer(tbuf);
136
    l=GWEN_Buffer_GetUsedBytes(tbuf);
137
    if (maxs>0 && l>maxs) {
138
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in local name (%d>%d)", l, maxs);
139
      GWEN_Buffer_free(tbuf);
140
      return GWEN_ERROR_INVALID;
141
    }
142
    GWEN_Buffer_free(tbuf);
143
  }
144
  else {
145
    DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing local name");
146
    return GWEN_ERROR_INVALID;
147
  }
148

    
149
  return 0;
150
}
151

    
152

    
153

    
154

    
155

    
156
int AB_Banking_CheckTransactionAgainstLimits_Recurrence(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
157
  if (lim) {
158
    /* check period */
159
    if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodMonthly) {
160
      int n;
161

    
162
      n=AB_Transaction_GetCycle(t);
163
      if (n==0) {
164
        DBG_ERROR(AQBANKING_LOGDOMAIN, "No cycle given");
165
        return GWEN_ERROR_INVALID;
166
      }
167

    
168
      if (!AB_TransactionLimits_ValuesCycleMonthHas(lim, n) &&
169
          !AB_TransactionLimits_ValuesCycleMonthHas(lim, 0)) {
170
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Month day \"%d\" not supported by bank", n);
171
        GWEN_Gui_ProgressLog2(0,
172
                              GWEN_LoggerLevel_Error,
173
                              I18N("Month day \"%d\" not supported by bank"),
174
                              n);
175
        return GWEN_ERROR_INVALID;
176
      }
177

    
178
      /* check execution day */
179
      n=AB_Transaction_GetExecutionDay(t);
180
      if (n==0) {
181
        DBG_ERROR(AQBANKING_LOGDOMAIN,
182
                  "No execution day given");
183
        return GWEN_ERROR_INVALID;
184
      }
185

    
186
      if (!AB_TransactionLimits_ValuesExecutionDayMonthHas(lim, n) &&
187
          !AB_TransactionLimits_ValuesExecutionDayMonthHas(lim, 0)) {
188
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Execution month day \"%d\" not supported by bank", n);
189
        GWEN_Gui_ProgressLog2(0,
190
                              GWEN_LoggerLevel_Error,
191
                              I18N("Execution month day \"%d\" not supported by bank"),
192
                              n);
193
        return GWEN_ERROR_INVALID;
194
      }
195
    } /* if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodMonthly) */
196
    else if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodWeekly) {
197
      int n;
198

    
199
      n=AB_Transaction_GetCycle(t);
200
      if (n==0) {
201
        DBG_ERROR(AQBANKING_LOGDOMAIN, "No cycle given");
202
        return GWEN_ERROR_INVALID;
203
      }
204

    
205
      if (!AB_TransactionLimits_ValuesCycleWeekHas(lim, n) &&
206
          !AB_TransactionLimits_ValuesCycleWeekHas(lim, 0)) {
207
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Week day \"%d\" not supported by bank", n);
208
        GWEN_Gui_ProgressLog2(0,
209
                              GWEN_LoggerLevel_Error,
210
                              I18N("Week day \"%d\" not supported by bank"),
211
                              n);
212
        return GWEN_ERROR_INVALID;
213
      }
214

    
215
      /* check execution day */
216
      n=AB_Transaction_GetExecutionDay(t);
217
      if (n==0) {
218
        DBG_ERROR(AQBANKING_LOGDOMAIN,
219
                  "No execution day given");
220
        return GWEN_ERROR_INVALID;
221
      }
222

    
223
      if (!AB_TransactionLimits_ValuesExecutionDayWeekHas(lim, n) &&
224
          !AB_TransactionLimits_ValuesExecutionDayWeekHas(lim, 0)) {
225
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Execution week day \"%d\" not supported by bank", n);
226
        GWEN_Gui_ProgressLog2(0,
227
                              GWEN_LoggerLevel_Error,
228
                              I18N("Execution week day \"%d\" not supported by bank"),
229
                              n);
230
        return GWEN_ERROR_INVALID;
231
      }
232
    } /* if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodWeekly) */
233
    else {
234
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Unsupported period %d", AB_Transaction_GetPeriod(t));
235
      return GWEN_ERROR_INVALID;
236
    }
237
  } /* if limits */
238

    
239
  return 0;
240
}
241

    
242

    
243

    
244
int AB_Banking_CheckTransactionAgainstLimits_ExecutionDate(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
245
  if (lim) {
246
    const GWEN_DATE *dt;
247

    
248
    /* check setup times */
249
    dt=AB_Transaction_GetFirstDate(t);
250
    if (dt) {
251
      GWEN_DATE *currDate;
252
      int diff;
253
      int n;
254
  
255
      currDate=GWEN_Date_CurrentDate();
256
      assert(currDate);
257
      diff=GWEN_Date_Diff(dt, currDate);
258
      GWEN_Date_free(currDate);
259
  
260
      /* check minimum setup time */
261
      n=AB_TransactionLimits_GetMinValueSetupTime(lim);
262
      if (n && diff<n) {
263
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Minimum setup time violated (given %d but required min=%d)", diff, n);
264
        GWEN_Gui_ProgressLog2(0,
265
                              GWEN_LoggerLevel_Error,
266
                              I18N("Minimum setup time violated. "
267
                                   "Dated transactions need to be at least %d days away"),
268
                              n);
269
        return GWEN_ERROR_INVALID;
270
      }
271
  
272
      /* check maximum setup time */
273
      n=AB_TransactionLimits_GetMaxValueSetupTime(lim);
274
      if (n && diff>n) {
275
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Maximum setup time violated (given %d but allowed max=%d)", diff, n);
276
        GWEN_Gui_ProgressLog2(0,
277
                              GWEN_LoggerLevel_Error,
278
                              I18N("Maximum setup time violated. "
279
                                   "Dated transactions need to be at most %d days away"),
280
                              n);
281
        return GWEN_ERROR_INVALID;
282
      }
283
    }
284
  }
285

    
286
  return 0;
287
}
288

    
289

    
290

    
291
int AB_Banking_CheckTransactionAgainstLimits_Date(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
292
  if (lim) {
293
    const GWEN_DATE *dt;
294

    
295
    dt=AB_Transaction_GetDate(t);
296
    if (dt) {
297
      GWEN_DATE *currDate;
298
      int diff;
299
      int n;
300

    
301
      currDate=GWEN_Date_CurrentDate();
302
      assert(currDate);
303
      diff=GWEN_Date_Diff(dt, currDate);
304
      GWEN_Date_free(currDate);
305

    
306
      /* check minimum setup time */
307
      n=AB_TransactionLimits_GetMinValueSetupTime(lim);
308
      if (n && diff<n) {
309
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Minimum setup time violated (given %d but required min=%d)", diff, n);
310
        GWEN_Gui_ProgressLog2(0,
311
                              GWEN_LoggerLevel_Error,
312
                              I18N("Minimum setup time violated. "
313
                                   "Dated transactions need to be at least %d days away"),
314
                              n);
315
        return GWEN_ERROR_INVALID;
316
      }
317

    
318
      /* check maximum setup time */
319
      n=AB_TransactionLimits_GetMaxValueSetupTime(lim);
320
      if (n && diff>n) {
321
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Maximum setup time violated (given %d but allowed max=%d)", diff, n);
322
        GWEN_Gui_ProgressLog2(0,
323
                              GWEN_LoggerLevel_Error,
324
                              I18N("Maximum setup time violated. "
325
                                   "Dated transactions need to be at most %d days away"),
326
                              n);
327
        return GWEN_ERROR_INVALID;
328
      }
329
    }
330
  }
331

    
332
  return 0;
333
}
334

    
335

    
336

    
337
int AB_Banking_CheckTransactionAgainstLimits_Sequence(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim) {
338
  if (lim) {
339
    const GWEN_DATE *dt;
340

    
341
    dt=AB_Transaction_GetDate(t);
342
    if (dt) {
343
      GWEN_DATE *currDate;
344
      int diff;
345
      int minTime=0;
346
      int maxTime=0;
347

    
348
      currDate=GWEN_Date_CurrentDate();
349
      assert(currDate);
350
      diff=GWEN_Date_Diff(dt, currDate);
351
      GWEN_Date_free(currDate);
352

    
353
      switch(AB_Transaction_GetSequence(t)) {
354
      case AB_Transaction_SequenceOnce:
355
        minTime=AB_TransactionLimits_GetMinValueSetupTimeOnce(lim);
356
        maxTime=AB_TransactionLimits_GetMaxValueSetupTimeOnce(lim);
357
        break;
358
      case AB_Transaction_SequenceFirst:
359
        minTime=AB_TransactionLimits_GetMinValueSetupTimeFirst(lim);
360
        maxTime=AB_TransactionLimits_GetMaxValueSetupTimeFirst(lim);
361
        break;
362
      case AB_Transaction_SequenceFollowing:
363
        minTime=AB_TransactionLimits_GetMinValueSetupTimeRecurring(lim);
364
        maxTime=AB_TransactionLimits_GetMaxValueSetupTimeRecurring(lim);
365
        break;
366
      case AB_Transaction_SequenceFinal:
367
        minTime=AB_TransactionLimits_GetMinValueSetupTimeFinal(lim);
368
        maxTime=AB_TransactionLimits_GetMaxValueSetupTimeFinal(lim);
369
        break;
370
      case AB_Transaction_SequenceUnknown:
371
        break;
372
      }
373

    
374
      if (minTime==0)
375
        minTime=AB_TransactionLimits_GetMinValueSetupTime(lim);
376
      if (maxTime==0)
377
        maxTime=AB_TransactionLimits_GetMaxValueSetupTime(lim);
378

    
379
      /* check minimum setup time */
380
      if (minTime && diff<minTime) {
381
        DBG_ERROR(AQBANKING_LOGDOMAIN,
382
                  "Minimum setup time violated (given %d but required min=%d for sequence type=%s)",
383
                  diff, minTime, AB_Transaction_Sequence_toString(AB_Transaction_GetSequence(t)));
384
        GWEN_Gui_ProgressLog2(0,
385
                              GWEN_LoggerLevel_Error,
386
                              I18N("Minimum setup time violated. "
387
                                   "Dated transactions need to be at least %d days away but %d days are requested"),
388
                              minTime, dt);
389
        return GWEN_ERROR_INVALID;
390
      }
391

    
392
      /* check maximum setup time */
393
      if (maxTime && diff>maxTime) {
394
        DBG_ERROR(AQBANKING_LOGDOMAIN,
395
                  "Maximum setup time violated (given %d but allowed max=%d for sequence type=%s)",
396
                  diff, maxTime, AB_Transaction_Sequence_toString(AB_Transaction_GetSequence(t)));
397
        GWEN_Gui_ProgressLog2(0,
398
                              GWEN_LoggerLevel_Error,
399
                              I18N("Maximum setup time violated. "
400
                                   "Dated transactions need to be at most %d days away but %d days are requested"),
401
                              maxTime, dt);
402
        return GWEN_ERROR_INVALID;
403
      }
404
    }
405
  }
406

    
407
  return 0;
408
}
409

    
410

    
411

    
412
static int _checkStringForSepaCharset(const char *s, int restricted) {
413
  char ascii_chars[]="'&*$%:?,-(+.)/ "; /* last is a blank! */
414
  const char *ascii;
415

    
416
#define RESTRICTED_CHARS_OFFSET 3
417

    
418
  assert(s);
419

    
420
  ascii=ascii_chars;
421
  if (restricted)
422
    ascii+=RESTRICTED_CHARS_OFFSET;
423

    
424
  while(*s) {
425
    unsigned char c=*s++;
426

    
427
    if (!((c>='A' && c<='Z') ||
428
          (c>='a' && c<='z') ||
429
          (c>='0' && c<='9') ||
430
          strchr(ascii, c)!=NULL)) {
431
      char errchr[7];
432
      int i = 0;
433

    
434
      if (c == 0xC3 && !restricted) {
435
        c = *s++;
436
        switch(c) {
437
        case 0x84:        /* AE */
438
        case 0xA4:        /* ae */
439
        case 0x96:        /* OE */
440
        case 0xB6:        /* oe */
441
        case 0x9C:        /* UE */
442
        case 0xBC:        /* ue */
443
        case 0x9F:        /* ss */
444
          if ((*s & 0xC0) != 0x80)
445
            break;
446
          /* these are no umlauts, after all, so fall through */
447

    
448
        default:
449
          errchr[i++]=0xC3;
450
          if ((c & 0xC0) == 0x80)
451
            errchr[i++]=c;
452
          else
453
            /* UTF-8 sequence ended prematurely */
454
            s--;
455
          break;
456
        }
457
      }
458
      else
459
        errchr[i++] = c;
460

    
461
      if (i) {
462
        while((*s & 0xC0) == 0x80)
463
          if (i<6)
464
            errchr[i++]=*s++;
465
          else {
466
            i++;
467
            s++;
468
          }
469

    
470
        if (i<7 && (i>1 || !(c & 0x80))) {
471
          errchr[i] = '\0';
472
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in string: '%s'",
473
                    errchr);
474
        }
475
        else {
476
          DBG_ERROR(AQBANKING_LOGDOMAIN, "String not properly UTF-8 encoded");
477
        }
478
        return GWEN_ERROR_BAD_DATA;
479
      }
480
    }
481
  }
482

    
483
  return 0;
484
}
485

    
486

    
487

    
488
/* This function does not check full UTF8, it only checks whether the given string contains characters
489
 * other than "A"-"Z", "a"-"z" and "0"-"9".
490
 * We don't use isalnum here because I'm not sure how that function handles UTF-8 chars with umlauts...
491
 */
492
static int _checkStringForAlNum(const char *s, int lcase) {
493
  assert(s);
494
  while(*s) {
495
    unsigned char c=*s;
496

    
497
    if (!((c>='0' && c<='9') ||
498
          (c>='A' && c<='Z') ||
499
          (lcase && c>='a' && c<='z'))) {
500
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in string: '%c'", c);
501
      return GWEN_ERROR_BAD_DATA;
502
    }
503
    s++;
504
  }
505

    
506
  return 0;
507
}
508

    
509

    
510

    
511
int AB_Banking_CheckTransactionForSepaConformity(const AB_TRANSACTION *t, int restricted) {
512
  if (t) {
513
    const char *s;
514
    int rv;
515

    
516
    s=AB_Transaction_GetLocalIban(t);
517
    if (!(s && *s)) {
518
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local IBAN in transaction");
519
      return GWEN_ERROR_BAD_DATA;
520
    }
521
    rv=_checkStringForAlNum(s, 1);
522
    if (rv<0) {
523
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local IBAN");
524
      return rv;
525
    }
526

    
527
    s=AB_Transaction_GetLocalBic(t);
528
    if (!(s && *s)) {
529
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local BIC in transaction");
530
      return GWEN_ERROR_BAD_DATA;
531
    }
532
    rv=_checkStringForAlNum(s, 0);
533
    if (rv<0) {
534
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local BIC");
535
      return rv;
536
    }
537

    
538
    s=AB_Transaction_GetRemoteIban(t);
539
    if (!(s && *s)) {
540
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote IBAN in transaction");
541
      return GWEN_ERROR_BAD_DATA;
542
    }
543
    rv=_checkStringForAlNum(s, 1);
544
    if (rv<0) {
545
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote IBAN");
546
      return rv;
547
    }
548

    
549
    s=AB_Transaction_GetRemoteBic(t);
550
    if (!(s && *s)) {
551
      if (strncmp(AB_Transaction_GetLocalIban(t), AB_Transaction_GetRemoteIban(t), 2)) {
552
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote BIC in transaction");
553
        return GWEN_ERROR_BAD_DATA;
554
      }
555
    }
556
    else {
557
      rv=_checkStringForAlNum(s, 0);
558
      if (rv<0) {
559
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote BIC");
560
        return rv;
561
      }
562
    }
563

    
564
    s=AB_Transaction_GetLocalName(t);
565
    if (!(s && *s)) {
566
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local name in transaction");
567
      return GWEN_ERROR_BAD_DATA;
568
    }
569
    rv=_checkStringForSepaCharset(s, restricted);
570
    if (rv<0) {
571
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local name");
572
      return rv;
573
    }
574

    
575
    s=AB_Transaction_GetRemoteName(t);
576
    if (!(s && *s)) {
577
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote name in transaction");
578
      return GWEN_ERROR_BAD_DATA;
579
    }
580
    rv=_checkStringForSepaCharset(s, restricted);
581
    if (rv<0) {
582
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote name");
583
      return rv;
584
    }
585
  }
586
  else {
587
    DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing transaction");
588
    return GWEN_ERROR_BAD_DATA;
589
  }
590

    
591
  DBG_INFO(AQBANKING_LOGDOMAIN, "Transaction conforms to restricted SEPA charset");
592
  return 0;
593
}
594

    
595

    
596

    
597
void AB_Banking_FillTransactionFromAccountSpec(AB_TRANSACTION *t, const AB_ACCOUNT_SPEC *as) {
598
  const char *s;
599

    
600
  assert(t);
601
  assert(as);
602

    
603
  /* unique account id */
604
  AB_Transaction_SetUniqueAccountId(t, AB_AccountSpec_GetUniqueId(as));
605

    
606
  /* local account */
607
  s=AB_AccountSpec_GetCountry(as);
608
  if (!s || !*s)
609
    s="de";
610
  AB_Transaction_SetLocalCountry(t, s);
611
  AB_Transaction_SetRemoteCountry(t, s);
612

    
613
  s=AB_AccountSpec_GetBankCode(as);
614
  if (s && *s)
615
    AB_Transaction_SetLocalBankCode(t, s);
616

    
617
  s=AB_AccountSpec_GetAccountNumber(as);
618
  if (s && *s)
619
    AB_Transaction_SetLocalAccountNumber(t, s);
620

    
621
  s=AB_AccountSpec_GetOwnerName(as);
622
  if (s && *s)
623
    AB_Transaction_SetLocalName(t, s);
624

    
625
  s=AB_AccountSpec_GetBic(as);
626
  if (s && *s)
627
    AB_Transaction_SetLocalBic(t, s);
628

    
629
  s=AB_AccountSpec_GetIban(as);
630
  if (s && *s)
631
    AB_Transaction_SetLocalIban(t, s);
632
}
633

    
634

    
635

    
636

    
637

    
638

    
639