]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Implement HKSAL5/HISAL5
authorHenryk Plötz <henryk@ploetzli.ch>
Mon, 20 Aug 2018 00:45:29 +0000 (02:45 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:29 +0000 (19:34 +0100)
fints/client.py
fints/fields.py
fints/formals.py
fints/segments/saldo.py

index e146635af2309531f986919a8fe9c1ef846d9642..119222a6b2746196c7e76260cb8821a1250bab59 100644 (file)
@@ -20,7 +20,7 @@ from .segments.accounts import HKSPA, HKSPA1, HISPA1
 from .segments.auth import HKTAB, HKTAN
 from .segments.dialog import HKSYN3, HISYN4
 from .segments.depot import HKWPD
-from .segments.saldo import HKSAL6, HKSAL7, HISAL6, HISAL7
+from .segments.saldo import HKSAL5, HKSAL6, HKSAL7, HISAL5, HISAL6, HISAL7
 from .segments.statement import HKKAZ
 from .segments.transfer import HKCCM, HKCCS
 from .utils import MT535_Miniparser, Password, mt940_to_array
@@ -204,25 +204,25 @@ class FinTS3Client:
             default=6
         )
 
-        if max_hksal_version in (1, 2, 3, 4, 5, 6):
-            seg = HKSAL6(
-                Account3.from_sepa_account(account),
-                False
-            )
-        elif max_hksal_version == 7:
-            seg = HKSAL7(
-                KTI1.from_sepa_account(account),
-                False
-            )
-        else:
+        clazz = {
+            5: HKSAL5,
+            6: HKSAL6,
+            7: HKSAL7,
+        }.get(max_hksal_version, None)
+
+        if clazz is None:
             raise ValueError('Unsupported HKSAL version {}'.format(max_hksal_version))
 
+        seg = clazz(
+            account=clazz._fields['account'].type.from_sepa_account(account),
+            all_accounts=False,
+        )
 
         with self._new_dialog() as dialog:
             response = dialog.send(seg)
         
         # find segment
-        seg = response.find_segment_first((HISAL6, HISAL7))
+        seg = response.find_segment_first((HISAL5, HISAL6, HISAL7))
         if seg:
             return seg.balance_booked.as_mt940_Balance()
 
index ef6dad8685301442a49d9e6e0c41cc72318a72b7..06ca8b707f88ce2214ff77f3a5f4f3d560640105 100644 (file)
@@ -215,7 +215,7 @@ class DigitsField(FieldRenderFormatStringMixin, DataElementField):
             raise TypeError("Only digits allowed for value of type 'dig': {!r}".format(value))
         return _value
 
-class FloatField(FieldRenderFormatStringMixin, DataElementField):
+class FloatField(DataElementField):
     type = 'float'
     _DOC_TYPE = float
     _FORMAT_STRING = "{:.12f}"  # Warning: Python's float is not exact!
@@ -232,8 +232,10 @@ class FloatField(FieldRenderFormatStringMixin, DataElementField):
         return float(_value.replace(",", "."))
 
     def _render_value(self, value):
-        retval = super()._render_value(value)
-        return retval.replace('.', ',').rstrip('0')
+        retval = self._FORMAT_STRING.format(value)
+        retval = retval.replace('.', ',').rstrip('0')
+        self._check_value_length(retval)
+        return retval
 
 class AmountField(FixedLengthMixin, FloatField):
     type = 'wrt'
index 6043e4cda9f5e12c5e4e1b5fd1d4c653e38f0faf..550596fa44eb20aadbbaa125aacd7806d9d348df 100644 (file)
@@ -357,6 +357,24 @@ class KTI1(DataElementGroup):
             )
         )
 
+class Account2(DataElementGroup):
+    """Kontoverbindung, version 2
+
+    Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation"""
+    account_number = DataElementField(type='id', _d="Konto-/Depotnummer")
+    subaccount_number = DataElementField(type='id', _d="Unterkontomerkmal")
+    country_identifier = DataElementField(type='ctr', _d="Länderkennzeichen")
+    bank_code = DataElementField(type='an', max_length=30, _d="Kreditinstitutscode")
+
+    @classmethod
+    def from_sepa_account(cls, acc):
+        return cls(
+            account_number=acc.accountnumber,
+            subaccount_number=acc.subaccount,
+            country_identifier='280',
+            bank_code=acc.blz,
+        )
+
 class Account3(DataElementGroup):
     """Kontoverbindung, version 3
 
@@ -460,6 +478,25 @@ class CreditDebit2(RepresentableEnum):
     CREDIT = 'C' #: Haben
     DEBIT = 'D' #: Soll
 
+class Balance1(DataElementGroup):
+    """Saldo, version 1
+
+    Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation"""
+    credit_debit = CodeField(enum=CreditDebit2, length=1, _d="Soll-Haben-Kennzeichen")
+    amount = DataElementField(type='wrt', _d="Wert")
+    currency = DataElementField(type='cur', _d="Währung")
+    date = DataElementField(type='dat', _d="Datum")
+    time = DataElementField(type='tim', required=False, _d="Uhrzeit")
+
+    def as_mt940_Balance(self):
+        from mt940.models import Balance
+        return Balance(
+            self.credit_debit.value,
+            "{:.12f}".format(self.amount).rstrip('0'),
+            self.date,
+            currency=self.currency
+        )
+
 class Balance2(DataElementGroup):
     """Saldo, version 2
 
index 19091a2470e2f12f45434550d73663493526e767..d211c184939f9822a69116633a66bb56afdd352e 100644 (file)
@@ -1,6 +1,6 @@
 from . import FinTS3SegmentOLD, FinTS3Segment
 
-from fints.formals import Account3, KTI1, Balance2, Amount1, Timestamp1
+from fints.formals import Account2, Account3, KTI1, Balance1, Balance2, Amount1, Timestamp1
 from fints.fields import DataElementGroupField, DataElementField
 
 
@@ -19,6 +19,31 @@ class HKSAL(FinTS3SegmentOLD):
         ]
         super().__init__(segno, data)
 
+class HKSAL5(FinTS3Segment):
+    """Saldenabfrage, version 5
+
+    Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation"""
+    account = DataElementGroupField(type=Account2, _d="Kontoverbindung Auftraggeber")
+    all_accounts = DataElementField(type='jn', _d="Alle Konten")
+    max_number_responses = DataElementField(type='num', max_length=4, required=False, _d="Maximale Anzahl Einträge")
+    touchdown_point = DataElementField(type='an', max_length=35, required=False, _d="Aufsetzpunkt")
+
+class HISAL5(FinTS3Segment):
+    """Saldenrückmeldung, version 5
+
+    Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation"""
+    account = DataElementGroupField(type=Account2, _d="Kontoverbindung Auftraggeber")
+    account_product = DataElementField(type='an', max_length=30, _d="Kontoproduktbezeichnung")
+    currency = DataElementField(type='cur', _d="Kontowährung")
+    balance_booked = DataElementGroupField(type=Balance1, _d="Gebuchter Saldo")
+    balance_pending = DataElementGroupField(type=Balance1, required=False, _d="Saldo der vorgemerkten Umsätze")
+    line_of_credit = DataElementGroupField(type=Amount1, required=False, _d="Kreditlinie")
+    available_amount = DataElementGroupField(type=Amount1, required=False, _d="Verfügbarer Betrag")
+    used_amount = DataElementGroupField(type=Amount1, required=False, _d="Bereits verfügter Betrag")
+    booking_date = DataElementField(type='dat', required=False, _d="Buchungsdatum des Saldos")
+    booking_time = DataElementField(type='tim', required=False, _d="Buchungsuhrzeit des Saldos")
+    date_due = DataElementField(type='dat', required=False, _d="Fälligkeit")
+
 class HKSAL6(FinTS3Segment):
     """Saldenabfrage, version 6
 
@@ -41,7 +66,7 @@ class HISAL6(FinTS3Segment):
     available_amount = DataElementGroupField(type=Amount1, required=False, _d="Verfügbarer Betrag")
     used_amount = DataElementGroupField(type=Amount1, required=False, _d="Bereits verfügter Betrag")
     overdraft = DataElementGroupField(type=Amount1, required=False, _d="Überziehung")
-    booking_time = DataElementGroupField(type=Timestamp1, required=False, _d="Buchungszeitpunkt")
+    booking_timestamp = DataElementGroupField(type=Timestamp1, required=False, _d="Buchungszeitpunkt")
     date_due = DataElementField(type='dat', required=False, _d="Fälligkeit")
 
 class HKSAL7(FinTS3Segment):
@@ -67,5 +92,5 @@ class HISAL7(FinTS3Segment):
     available_amount = DataElementGroupField(type=Amount1, required=False, _d="Verfügbarer Betrag")
     used_amount = DataElementGroupField(type=Amount1, required=False, _d="Bereits verfügter Betrag")
     overdraft = DataElementGroupField(type=Amount1, required=False, _d="Überziehung")
-    booking_time = DataElementGroupField(type=Timestamp1, required=False, _d="Buchungszeitpunkt")
+    booking_timestamp = DataElementGroupField(type=Timestamp1, required=False, _d="Buchungszeitpunkt")
     date_due = DataElementField(type='dat', required=False, _d="Fälligkeit")