]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Implement direct debit
authorRaphael Michel <mail@raphaelmichel.de>
Wed, 25 Jul 2018 16:49:13 +0000 (18:49 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Thu, 26 Jul 2018 20:27:05 +0000 (22:27 +0200)
fints/client.py
fints/segments/debit.py [new file with mode: 0644]

index 03e189f9a43bd5cf9937d5d8783c87d0af2a5eee..0fbad86eb3555f74108e9017bb2629a8ea7a7c9f 100644 (file)
@@ -6,6 +6,7 @@ from decimal import Decimal
 from mt940.models import Balance
 from sepaxml import SepaTransfer
 
+from fints.segments.debit import HKDSE, HKDME
 from .connection import FinTSHTTPSConnection
 from .dialog import FinTSDialog
 from .message import FinTSMessage
@@ -319,6 +320,40 @@ class FinTS3Client:
         logger.debug('Got response: {}'.format(resp))
         return self._tan_requiring_response(dialog, resp)
 
+    def _get_start_sepa_debit_message(self, dialog, account: SEPAAccount, pain_message: str, tan_method,
+                                      tan_description, multiple, control_sum, currency, book_as_single):
+        if multiple:
+            if not control_sum:
+                raise ValueError("Control sum required.")
+            segreq = HKDME(3, account, pain_message, control_sum, currency, book_as_single)
+        else:
+            segreq = HKDSE(3, account, pain_message)
+        segtan = HKTAN(4, '4', '', tan_description, tan_method.version)
+        return self._new_message(dialog, [
+            segreq,
+            segtan
+        ])
+
+    def start_sepa_debit(self, account: SEPAAccount, pain_message: str, tan_method, tan_description='',
+                         multiple=False, control_sum=None, currency='EUR', book_as_single=False):
+        dialog = self._new_dialog()
+        dialog.sync()
+        dialog.tan_mechs = [tan_method]
+        dialog.init()
+
+        with self.pin.protect():
+            logger.debug('Sending: {}'.format(self._get_start_sepa_debit_message(
+                dialog, account, pain_message, tan_method, tan_description, multiple, control_sum, currency,
+                book_as_single
+            )))
+
+        resp = dialog.send(self._get_start_sepa_debit_message(
+            dialog, account, pain_message, tan_method, tan_description, multiple, control_sum, currency,
+            book_as_single
+        ))
+        logger.debug('Got response: {}'.format(resp))
+        return self._tan_requiring_response(dialog, resp)
+
     def _tan_requiring_response(self, dialog, resp):
         seg = resp._find_segment('HITAN')
         s = split_for_data_groups(seg)
diff --git a/fints/segments/debit.py b/fints/segments/debit.py
new file mode 100644 (file)
index 0000000..0c349ca
--- /dev/null
@@ -0,0 +1,48 @@
+from . import FinTS3Segment
+from ..models import SEPAAccount
+
+
+class HKDSE(FinTS3Segment):
+    """
+    HKDSE (Einreichung terminierter SEPA-Einzellastschrift)
+    Section C.10.2.5.4.1
+    """
+    type = 'HKDSE'
+
+    def __init__(self, segno, account: SEPAAccount, pain_msg):
+        self.version = 1
+        sepa_descriptor = 'urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.008.003.02'
+        msg = ':'.join([
+            account.iban,
+            account.bic
+        ])
+        data = [
+            msg,
+            sepa_descriptor,
+            '@{}@{}'.format(len(pain_msg), pain_msg)
+        ]
+        super().__init__(segno, data)
+
+
+class HKDME(FinTS3Segment):
+    """
+    HKDME (Einreichung terminierter SEPA-Sammellastschrift)
+    Section C.10.3.2.2.1
+    """
+    type = 'HKDME'
+
+    def __init__(self, segno, account: SEPAAccount, pain_msg, control_sum, currency, book_as_single):
+        self.version = 1
+        sepa_descriptor = 'urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.008.003.02'
+        msg = ':'.join([
+            account.iban,
+            account.bic
+        ])
+        data = [
+            msg,
+            str(control_sum).replace('.', ',') + ':' + currency,
+            'J' if book_as_single else '',
+            sepa_descriptor,
+            '@{}@{}'.format(len(pain_msg), pain_msg)
+        ]
+        super().__init__(segno, data)