]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Bank transfer patch bei Daniel Nowak
authorDaniel Nowak <noreply@users.noreply.github.com>
Mon, 23 Jul 2018 17:59:08 +0000 (19:59 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 23 Jul 2018 17:59:08 +0000 (19:59 +0200)
fints/client.py
fints/dialog.py
fints/segments/sepaueb.py [new file with mode: 0644]

index a3b7151887f42bf85d92a2e14e8c79c5be37249d..8f4f56e92191c3f83143a9f0c7434a187a6f3b40 100644 (file)
@@ -10,6 +10,11 @@ from .segments.accounts import HKSPA
 from .segments.statement import HKKAZ
 from .segments.saldo import HKSAL
 from .segments.depot import HKWPD
+from .segments.sepaueb import HKCCS
+from .segments.sepaueb import HKTAN
+from .segments.sepaueb import HKTAB
+from .segments.message import HNHBK
+from .message import FinTSResponse
 from .utils import mt940_to_array, MT535_Miniparser, split_for_data_groups, split_for_data_elements, Password
 from mt940.models import Balance
 
@@ -235,6 +240,131 @@ class FinTS3Client:
             )
         ])
 
+    # D. Nowak
+    def put_sepa_tan(self, arg):
+
+        data = str(arg['response'])
+
+        res = FinTSResponse(data)
+        seg = res._find_segment('HITAN')
+        seg = split_for_data_groups(seg)
+        aref = seg[3]
+        segTAN = HKTAN(3, 2, aref, '')
+
+        self.blz = arg['dialog'].blz
+        self.username = arg['dialog'].username
+        self.pin = arg['dialog'].pin
+        self.systemid = arg['dialog'].systemid
+        self.dialogid = arg['dialog'].dialogid
+        self.msgno = arg['dialog'].msgno
+        self.tan_mechs = []
+        self.tan_mechs = [arg['TAN-Verfahren']]
+        self.pintan = ':'.join([self.pin, arg['tan']])
+        msg = FinTSMessage(self.blz, self.username, self.pintan, self.systemid, self.dialogid, self.msgno, [
+            segTAN
+        ], self.tan_mechs)
+
+        res = arg['dialog'].send(msg)
+        arg['dialog'].end()
+
+        return 'Ok'
+
+    # D. Nowak
+    def put_sepa_ueberweisung(self, account, arg):
+        # Diese Funktion erstellt eine neue SEPA-Überweisung
+        self.tan_bezeichnung = arg['TAN-Bezeichnung']
+        dialog = self._new_dialog()
+        dialog.sync()
+
+        # TAN-Verfahren für Dialoginitialisierung ändern
+        dialog.tan_mechs = [arg['TAN-Verfahren']]
+
+        dialog.init()
+
+        def _get_msg():
+            segHKCCS = HKCCS(3, account, arg)
+            segHKTAN = HKTAN(4, 4, '', self.tan_bezeichnung)
+            return self._new_message(dialog, [
+                segHKCCS,
+                segHKTAN
+            ])
+
+        with self.pin.protect():
+            logger.debug('Sending HKCCS: {}'.format(_get_msg()))
+
+
+        resp = None
+        resp = dialog.send(_get_msg())
+        logger.debug('Got HKCCS response: {}'.format(resp))
+
+        response = {}
+        response['response'] = resp
+        response['dialog'] = dialog
+
+        return response
+
+    # D. Nowak
+    def get_tan_verfahren(self):
+        # Diese Funktion ermittelt die zugelassenen TAN-Verfahren und deren Parameter
+        dialog = self._new_dialog()
+        dialog.init()
+
+        # TAN-Verfahren ermitteln
+        res = FinTSResponse(str(dialog.bpd)        )
+        seg = res._find_segment('HIRMS')
+        deg = split_for_data_groups(seg)
+        for de in deg:
+            if de[0:4] == '3920':
+                tan_verf = []
+                d = split_for_data_elements(de)
+                for i in range (3, len(d)):
+                    tan_verf.append(d[i])
+
+        # Parameter der TAN-Verfahren ermitteln
+        seg = res._find_segments('HITANS')
+        verfahren = []
+        for t in tan_verf:
+            for s in seg:
+                ct = s.find(t)
+                c0 = s[ct:].find(':00:')     # Initialisierungsverfahren mit Klartext-PIN ohne TAN
+                if ct != -1 and c0 != -1:
+                    deg = s[ct:ct + c0 + 7]
+                    de = split_for_data_elements(deg)
+
+                    v = {}
+                    if de[3] == 'HHDOPT1':
+                        v['Bezeichnung'] = de[5]
+                    else:
+                        v['Bezeichnung'] = de[2]
+                    v['Code'] = de[0]
+                    v['TAN-erf'] = de[len(de) - 2]
+                    verfahren.append(v)
+
+        return verfahren
+
+    # D. Nowak
+    def get_tan_bezeichnung(self):
+        dialog = self._new_dialog()
+        dialog.sync()
+        dialog.init()
+
+        def _get_msg():
+            return self._new_message(dialog, [
+                HKTAB(3)
+            ])
+
+        with self.pin.protect():
+            logger.debug('Sending HKTAB: {}'.format(_get_msg()))
+
+        resp = dialog.send(_get_msg())
+        logger.debug('Got HKTAB response: {}'.format(resp))
+        dialog.end()
+
+        seg = resp._find_segment('HITAB')
+        deg = split_for_data_groups(seg)
+
+        return deg[2]
+
 
 class FinTS3PinTanClient(FinTS3Client):
 
index 6604f8f80e21bf4d3dd5aae428769efe98528fe3..0b6a56585327b66338120030e0e7c58709805b26 100644 (file)
@@ -84,6 +84,9 @@ class FinTSDialog:
         self.dialogid = resp.get_dialog_id()
         logger.info('Received dialog ID: {}'.format(self.dialogid))
 
+        # D. Nowak: BPD sichern
+        self.bpd = resp
+
         return self.dialogid
 
     def end(self):
diff --git a/fints/segments/sepaueb.py b/fints/segments/sepaueb.py
new file mode 100644 (file)
index 0000000..576b767
--- /dev/null
@@ -0,0 +1,100 @@
+from . import FinTS3Segment
+import datetime
+
+class HKCCS(FinTS3Segment):
+    """
+    HKCCS (SEPA Überweisung übertragen)
+    Section C.2.1.2
+    """
+    type = 'HKCCS'
+
+    def __init__(self, segno, account, arg):
+        self.version = 1
+        sepadescriptor = 'urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.001.03'
+        painmsg = self.create_pain(account, arg)
+        laenge = '@' + str(len(painmsg)) + '@'
+        msg = ':'.join([
+            account.iban,
+            account.bic
+        ])
+        data = [
+            msg,
+            sepadescriptor,
+            '@{}@{}'.format(len(painmsg), painmsg)
+        ]
+        super().__init__(segno, data)
+
+    def create_pain(self, account, arg):
+        pain = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
+        pain += '<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" ' \
+                'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' \
+                'xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd">'
+        pain += '<CstmrCdtTrfInitn>'
+        pain += '<GrpHdr>'
+        pain += '<MsgId>' + datetime.datetime.now().isoformat()[:-2] + '</MsgId>'
+        pain += '<CreDtTm>' + datetime.datetime.now().replace(microsecond=0).isoformat() + '</CreDtTm>'
+        pain += '<NbOfTxs>1</NbOfTxs>'
+        pain += '<CtrlSum>' + arg['CtrlSum'] + '</CtrlSum>'
+        pain += '<InitgPty><Nm>' + arg['Nm']+ '</Nm></InitgPty>'
+        pain += '</GrpHdr>'
+        pain += '<PmtInf>'
+        pain += '<PmtInfId>' + datetime.datetime.now().isoformat()[:-2] + '</PmtInfId>'
+        pain += '<PmtMtd>TRF</PmtMtd><NbOfTxs>1</NbOfTxs>'
+        pain += '<CtrlSum>' + arg['CtrlSum'] + '</CtrlSum>'
+        pain += '<PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf>'
+        pain += '<ReqdExctnDt>1999-01-01</ReqdExctnDt>'
+        pain += '<Dbtr><Nm>' + arg['Nm'] + '</Nm></Dbtr>'
+        pain += '<DbtrAcct><Id><IBAN>' + account.iban + '</IBAN></Id></DbtrAcct>'
+        pain += '<DbtrAgt><FinInstnId><BIC>' + account.bic + '</BIC></FinInstnId></DbtrAgt>'
+        pain += '<ChrgBr>SLEV</ChrgBr>'
+        pain += '<CdtTrfTxInf>'
+        pain += '<PmtId><EndToEndId>NOTPROVIDED</EndToEndId></PmtId>'
+        pain += '<Amt><InstdAmt Ccy="EUR">' + arg['CtrlSum'] + '</InstdAmt></Amt>'
+        pain += '<CdtrAgt><FinInstnId><BIC>' + arg['DbtrAgt'] + '</BIC></FinInstnId></CdtrAgt>'
+        pain += '<Cdtr><Nm>' + arg['Nm'] + '</Nm></Cdtr>'
+        pain += '<CdtrAcct><Id><IBAN>' + arg['DbtrAcct'] + '</IBAN></Id></CdtrAcct>'
+        pain += '<RmtInf><Ustrd>' + arg['Ustrd'] + '</Ustrd></RmtInf>'
+        pain += '</CdtTrfTxInf>'
+        pain += '</PmtInf>'
+        pain += '</CstmrCdtTrfInitn>'
+        pain += '</Document>'
+
+        return pain
+
+class HKTAN(FinTS3Segment):
+    """
+    HKTAN (TAN-Verfahren festlegen)
+    Section C.2.1.2
+    """
+    type = 'HKTAN'
+
+    def __init__(self, segno, prozess, aref, medium):
+        self.version = 3
+        if prozess == 4:
+            if medium == '':
+                data = [
+                    prozess
+                ]
+            else:
+                data = [
+                    prozess,'','','','','','','', medium
+            ]
+        else:
+            data = [
+                prozess,'', aref, '', 'N'
+            ]
+        super().__init__(segno, data)
+
+class HKTAB(FinTS3Segment):
+    """
+    HKTAB (Verfügbarre TAN-Medien ermitteln)
+    Section C.2.1.2
+    """
+    type = 'HKTAB'
+
+    def __init__(self, segno):
+        self.version = 4
+        data = [
+            '0','A'
+        ]
+        super().__init__(segno, data)