]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Fix escaping problems with GAD banks
authorRaphael Michel <mail@raphaelmichel.de>
Wed, 14 Jun 2017 14:55:34 +0000 (16:55 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Wed, 14 Jun 2017 14:56:08 +0000 (16:56 +0200)
fints/client.py
fints/message.py
fints/segments/statement.py
fints/utils.py

index f9fe7551a4eba001ac2ed1373e71de9dca1833f7..659e0ef21f09e44c45b42b71137b437834d9dc48 100644 (file)
@@ -10,7 +10,7 @@ from .segments.accounts import HKSPA
 from .segments.statement import HKKAZ
 from .segments.saldo import HKSAL
 from .segments.depot import HKWPD
-from .utils import mt940_to_array, MT535_Miniparser
+from .utils import mt940_to_array, MT535_Miniparser, split_for_data_groups, split_for_data_elements
 from mt940.models import Balance
 
 logger = logging.getLogger(__name__)
@@ -69,6 +69,7 @@ class FinTS3Client:
         while HKKAZ.type in touchdowns:
             logger.info('Fetching more results ({})...'.format(touchdown_counter))
             msg = self._create_statement_message(dialog, account, start_date, end_date, touchdowns[HKKAZ.type])
+            logger.debug('Send message: {}'.format(msg))
 
             resp = dialog.send(msg)
             responses.append(resp)
@@ -134,7 +135,7 @@ class FinTS3Client:
 
         # find segment and split up to balance part
         seg = resp._find_segment('HISAL')
-        arr = seg.split('+')[4].split(':')
+        arr = split_for_data_elements(split_for_data_groups(seg)[4])
 
         # get balance date
         date = datetime.datetime.strptime(arr[3], "%Y%m%d").date()
index b574ed9a308b59f4f96f93c5869b2a203f34b833..b6be2ae8d5fd653149b7814f7f0f6855da04a833 100644 (file)
@@ -1,6 +1,7 @@
 import random
 import re
 
+from fints.utils import split_for_data_groups, split_for_data_elements, fints_unescape
 from .segments.message import HNHBK, HNHBS, HNSHA, HNSHK, HNVSD, HNVSK
 
 
@@ -156,20 +157,20 @@ class FinTSResponse:
         for msgseg in msg.encrypted_segments:
             seg = self._find_segment_for_reference('HIRMS', msgseg)
             if seg:
-                parts = seg.split('+')[1:]
+                parts = split_for_data_groups(seg)[1:]
                 for p in parts:
-                    psplit = p.split(':')
+                    psplit = split_for_data_elements(p)
                     if psplit[0] == "3040":
                         td = psplit[3]
-                        touchdown[msgseg.type] = td
+                        touchdown[msgseg.type] = fints_unescape(td)
         return touchdown
 
     def _get_segment_max_version(self, name):
         v = 3
         segs = self._find_segments(name)
         for s in segs:
-            parts = s.split('+')
-            segheader = parts[0].split(':')
+            parts = split_for_data_groups(s)
+            segheader = split_for_data_elements(parts[0])
             curver = int(segheader[2])
             if curver > v:
                 v = curver
index 5f3f891f2a6e0e6e21cf69225738d20d5447c3b9..71114e4624f7087e298bba86bc09550dacd181e4 100644 (file)
@@ -1,9 +1,12 @@
+from fints.utils import fints_escape
 from . import FinTS3Segment
 
 
 class HKKAZ(FinTS3Segment):
     """
     HKKAZ (Kontoumsätze)
+
+    Refs: http://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Messages_Geschaeftsvorfaelle_2015-08-07_final_version.pdf
     Section C.2.1.1.1.2
     """
     type = 'HKKAZ'
@@ -17,6 +20,6 @@ class HKKAZ(FinTS3Segment):
             date_start.strftime('%Y%m%d'),
             date_end.strftime('%Y%m%d'),
             '',
-            touchdown if touchdown is not None else ''
+            fints_escape(touchdown) if touchdown is not None else ''
         ]
         super().__init__(segno, data)
index c06ec82d68e34d41f253ec896d35953f63162c13..9c2a86da38440c74a68cee1b0ad881af698a94dd 100644 (file)
@@ -17,6 +17,28 @@ def print_segments(message):
         print(u"{}: {}".format(idx, seg.encode('utf-8')))
 
 
+def fints_escape(content):
+    """
+    Escape strings
+
+    Ref:  https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Formals_2017-05-11_final_version.pdf
+    Section  H.1.1
+    """
+    return content.replace('?', '??').replace('+', '?+').replace(':', '?:').replace("'", "?'")
+
+
+def fints_unescape(content):
+    return content.replace('??', '?').replace("?'", "'").replace('?+', '+').replace('?:', ':')
+
+
+def split_for_data_groups(seg):
+    return re.split('\+(?<!\?\+)', seg)
+
+
+def split_for_data_elements(deg):
+    return re.split(':(?<!\?:)', deg)
+
+
 class MT535_Miniparser:
     re_identification = re.compile(r"^:35B:ISIN\s(.*)\|(.*)\|(.*)$")
     re_marketprice = re.compile(r"^:90B::MRKT\/\/ACTU\/([A-Z]{3})(\d*),{1}(\d*)$")