From: Raphael Michel Date: Fri, 22 Feb 2019 11:20:39 +0000 (+0100) Subject: Add support for HKCAZ X-Git-Tag: v2.1.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32a3739dc73a55398ec6ed622c9f65447fb52b6f;p=thirdparty%2Fpython-fints.git Add support for HKCAZ --- diff --git a/docs/reading.rst b/docs/reading.rst index 851d7d4..e9b889e 100644 --- a/docs/reading.rst +++ b/docs/reading.rst @@ -50,7 +50,7 @@ You can fetch the banking statement of an account within a certain timeframe wit operation. .. autoclass:: fints.client.FinTS3Client - :members: get_transactions + :members: get_transactions, get_transactions_xml :noindex: This method will return a list of ``Transaction`` objects from the ``mt-940`` library. You can find more information diff --git a/fints/client.py b/fints/client.py index 1b6b06a..4dab5f8 100644 --- a/fints/client.py +++ b/fints/client.py @@ -17,7 +17,7 @@ from .exceptions import * from .formals import ( CUSTOMER_ID_ANONYMOUS, KTI1, BankIdentifier, DescriptionRequired, SynchronizationMode, TANMediaClass4, TANMediaType2, -) + SupportedMessageTypes) from .message import FinTSInstituteMessage from .models import SEPAAccount from .parser import FinTS3Serializer @@ -36,7 +36,7 @@ from .segments.depot import HKWPD5, HKWPD6 from .segments.dialog import HIRMG2, HIRMS2, HISYN4, HKSYN3 from .segments.journal import HKPRO3, HKPRO4 from .segments.saldo import HKSAL5, HKSAL6, HKSAL7 -from .segments.statement import DKKKU2, HKKAZ5, HKKAZ6, HKKAZ7 +from .segments.statement import DKKKU2, HKKAZ5, HKKAZ6, HKKAZ7, HKCAZ1 from .segments.transfer import HKCCM1, HKCCS1 from .types import SegmentSequence from .utils import ( @@ -508,6 +508,40 @@ class FinTS3Client: return statement + def get_transactions_xml(self, account: SEPAAccount, start_date: datetime.date = None, + end_date: datetime.date = None) -> list: + """ + Fetches the list of transactions of a bank account in a certain timeframe as camt.052.001.02 XML files. + + :param account: SEPA + :param start_date: First day to fetch + :param end_date: Last day to fetch + :return: A list of binary XML objects + """ + + with self._get_dialog() as dialog: + hkcaz = self._find_highest_supported_command(HKCAZ1) + + logger.info('Start fetching from {} to {}'.format(start_date, end_date)) + responses = self._fetch_with_touchdowns( + dialog, + lambda touchdown: hkcaz( + account=hkcaz._fields['account'].type.from_sepa_account(account), + all_accounts=False, + date_start=start_date, + date_end=end_date, + touchdown_point=touchdown, + supported_camt_messages=SupportedMessageTypes('urn:iso:std:iso:20022:tech:xsd:camt.052.001.02'), + ), + 'HICAZ' + ) + logger.info('Fetching done.') + + xml_streams = [] + for seg in responses: + xml_streams.append(seg.statement_booked) + return xml_streams + def get_credit_card_transactions(self, account: SEPAAccount, credit_card_number: str, start_date: datetime.date = None, end_date: datetime.date = None): # FIXME Reverse engineered, probably wrong with self._get_dialog() as dialog: diff --git a/fints/formals.py b/fints/formals.py index 8cc5477..2bd5548 100644 --- a/fints/formals.py +++ b/fints/formals.py @@ -953,3 +953,12 @@ class GetSEPAAccountParameter1(DataElementGroup): national_account_allowed = DataElementField(type='jn', _d="Nationale Kontoverbindung erlaubt") structured_purpose_allowed = DataElementField(type='jn', _d="Strukturierter Verwendungszweck erlaubt") supported_sepa_formats = DataElementField(type='an', max_length=256, max_count=99, required=False, _d="Unterstützte SEPA-Datenformate") + + +class SupportedMessageTypes(DataElementGroup): + """Unterstützte camt-Messages + + Source: Messages - Multibankfähige Geschäftsvorfälle (SEPA) - C.2.3.1.1.1 + """ + expected_type = AlphanumericField(_d='Unterstützte camt-messages') + # TODO: Support passing an arbitrary number of values here diff --git a/fints/segments/statement.py b/fints/segments/statement.py index 9fa6b5e..aa9e020 100644 --- a/fints/segments/statement.py +++ b/fints/segments/statement.py @@ -1,5 +1,5 @@ from fints.fields import DataElementField, DataElementGroupField -from fints.formals import KTI1, Account2, Account3, QueryCreditCardStatements2 +from fints.formals import KTI1, Account2, Account3, QueryCreditCardStatements2, SupportedMessageTypes from .base import FinTS3Segment, ParameterSegment @@ -87,3 +87,29 @@ class DIKKUS2(ParameterSegment): Source: Reverse engineered""" parameter = DataElementGroupField(type=QueryCreditCardStatements2, _d="Parameter Kreditkartenumsätze anfordern") + + +class HKCAZ1(FinTS3Segment): + """Kontoumsätze anfordern/Zeitraum, version 5 + + Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation""" + account = DataElementGroupField(type=KTI1, _d="Kontoverbindung international") + supported_camt_messages = DataElementGroupField(type=SupportedMessageTypes, _d="Kontoverbindung international") + all_accounts = DataElementField(type='jn', _d="Alle Konten") + date_start = DataElementField(type='dat', required=False, _d="Von Datum") + date_end = DataElementField(type='dat', required=False, _d="Bis Datum") + 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 HICAZ1(FinTS3Segment): + """Kontoumsätze rückmelden/Zeitraum, version 1 + + Source: HBCI Homebanking-Computer-Interface, Schnittstellenspezifikation""" + account = DataElementGroupField(type=Account3, _d="Kontoverbindung Auftraggeber") + all_accounts = DataElementField(type='jn', _d="Alle Konten") + camt_descriptor = DataElementField(type='an', _d="camt-Deskriptor") + # According to specification, statement_booked is a DEG with one binary XML *per day*. However, banks apparently + # send just one XML instead. + statement_booked = DataElementField(type='bin', _d="Gebuchte Umsätze") + statement_pending = DataElementField(type='bin', required=False, _d="Nicht gebuchte Umsätze")