diff --git a/fints/client.py b/fints/client.py index 3ecfbfc..57d2c4d 100644 --- a/fints/client.py +++ b/fints/client.py @@ -17,7 +17,7 @@ from .formals import ( CUSTOMER_ID_ANONYMOUS, KTI1, BankIdentifier, DescriptionRequired, SynchronizationMode, TANMediaClass4, TANMediaType2, - SupportedMessageTypes, TANUsageOption + SupportedMessageTypes, StatementFormat, TANUsageOption ) from .message import FinTSInstituteMessage from .models import SEPAAccount @@ -37,7 +37,7 @@ 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, HKCAZ1 +from .segments.statement import DKKKU2, HKKAZ5, HKKAZ6, HKKAZ7, HKCAZ1, HKKAU2, HKKAU1, HKEKA3, HKEKA4, HKEKA5 from .segments.transfer import HKCCM1, HKCCS1, HKIPZ1, HKIPM1 from .types import SegmentSequence from .utils import ( @@ -733,6 +733,55 @@ def get_communication_endpoints(self): return responses + def get_statements(self, account: SEPAAccount): + """ + Retrieve list of statements of an account. + + :param account: SEPAAccount to retrieve statements for. + :return: List of HIKAU objects + """ + with self._get_dialog() as dialog: + hkkau = self._find_highest_supported_command(HKKAU1, HKKAU2) + + responses = self._fetch_with_touchdowns( + dialog, + lambda touchdown: hkkau( + account=hkkau._fields['account'].type.from_sepa_account(account), + touchdown_point=touchdown, + ), + lambda response: response, + 'HIKAU' + ) + + return responses + + def _get_statement(self, command_seg, response): + for resp in response.response_segments(command_seg, 'HIEKA'): + return resp + + def get_statement(self, account: SEPAAccount, number: int, year: int, format: StatementFormat = None): + """ + Retrieve a given statement of an account. + + :param account: SEPAAccount to retrieve statement for. + :param number: Number of the statement to retrieve. + :param year: Year of the statement to retrieve. + :param format: Format to retrieve the statement in. + :return: HIEKA object + """ + with self._get_dialog() as dialog: + hkeka = self._find_highest_supported_command(HKEKA3, HKEKA4, HKEKA5) + + seg = hkeka( + account=hkeka._fields['account'].type.from_sepa_account(account), + statement_format=format, + statement_number=number, + statement_year=year + ) + + response = self._send_with_possible_retry(dialog, seg, self._get_statement) + return response + def _find_supported_sepa_version(self, candidate_versions): hispas = self.bpd.find_segment_first('HISPAS') if not hispas: diff --git a/fints/formals.py b/fints/formals.py index 48edaf7..d3cddf5 100644 --- a/fints/formals.py +++ b/fints/formals.py @@ -1043,3 +1043,31 @@ class BookedCamtStatements1(DataElementGroup): Source: Messages - Multibankfähige Geschäftsvorfälle (SEPA)""" camt_statements = DataElementField(type='bin', min_count=1, required=True, _d="camt-Umsätze gebucht") + + +@document_enum +class StatementFormat(RepresentableEnum): + """Kontoauszugsformat + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + MT_940 = '1' # doc: S.W.I.F.T. MT940 + ISO_8583 = '2' # doc: ISO 8583 + PDF = '3' # doc: printable format (e.g., PDF) + + +@document_enum +class Confirmation(RepresentableEnum): + """Quittierung + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + NOT_REQUIRED = '0' # doc: Nicht Notwendig + CONFIRMED = '1' # doc: Quittiert + AWAITING_CONFIRMATION = '2' # doc: Quittierung offen + + +class ReportPeriod2(DataElementGroup): + """Berichtszeitraum, version 2 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + start_date = DataElementField(type='dat', _d="Startdatum") + end_date = DataElementField(type='dat', required=False, _d="Enddatum") diff --git a/fints/segments/statement.py b/fints/segments/statement.py index c6c082f..bc45c95 100644 --- a/fints/segments/statement.py +++ b/fints/segments/statement.py @@ -1,6 +1,6 @@ -from fints.fields import DataElementField, DataElementGroupField +from fints.fields import DataElementField, DataElementGroupField, CodeField from fints.formals import KTI1, Account2, Account3, QueryCreditCardStatements2, SupportedMessageTypes, \ - BookedCamtStatements1 + BookedCamtStatements1, StatementFormat, Confirmation, ReportPeriod2 from .base import FinTS3Segment, ParameterSegment @@ -111,3 +111,143 @@ class HICAZ1(FinTS3Segment): camt_descriptor = DataElementField(type='an', _d="camt-Deskriptor") statement_booked = DataElementGroupField(type=BookedCamtStatements1, _d="Gebuchte Umsätze") statement_pending = DataElementField(type='bin', required=False, _d="Nicht gebuchte Umsätze") + + +class HKKAU1(FinTS3Segment): + """Übersicht Kontoauszüge, version 1 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + account = DataElementGroupField(type=Account3, _d="Kontoverbindung Auftraggeber") + 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 HKKAU2(FinTS3Segment): + """Übersicht Kontoauszüge, version 2 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + account = DataElementGroupField(type=KTI1, _d="Kontoverbindung international") + 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 HIKAU1(FinTS3Segment): + """Übersicht Kontoauszüge, version 1 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + statement_number = DataElementField(type='num', max_length=5, _d="Kontoauszugsnummer") + confirmation = CodeField(enum=Confirmation, length=1, _d="Quittierung") + collection_possible = DataElementField(type='jn', _d="Abholung möglich J/N") + year = DataElementField(type='num', length=4, required=False, _d="Jahr") + date_created = DataElementField(type='dat', required=False, _d="Datum der Erstellung") + time_created = DataElementField(type='tim', required=False, _d="Uhrzeit der Erstellung") + creation_type = DataElementField(type='an', max_length=30, required=False, _d="Erstellart") + + +class HIKAU2(FinTS3Segment): + """Übersicht Kontoauszüge, version 2 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + statement_number = DataElementField(type='num', max_length=5, _d="Kontoauszugsnummer") + confirmation = CodeField(enum=Confirmation, length=1, _d="Quittierung") + collection_possible = DataElementField(type='jn', _d="Abholung möglich J/N") + year = DataElementField(type='num', length=4, required=False, _d="Jahr") + date_created = DataElementField(type='dat', required=False, _d="Datum der Erstellung") + time_created = DataElementField(type='tim', required=False, _d="Uhrzeit der Erstellung") + creation_type = DataElementField(type='an', max_length=30, required=False, _d="Erstellart") + + +class HKEKA3(FinTS3Segment): + """Kontoauszug anfordern, version 3 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + account = DataElementGroupField(type=Account3, _d="Kontoverbindung Auftraggeber") + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_number = DataElementField(type='num', max_length=5, _d="Kontoauszugsnummer") + statement_year = DataElementField(type='num', length=4, _d="Kontoauszugsjahr") + 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 HKEKA4(FinTS3Segment): + """Kontoauszug anfordern, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + account = DataElementGroupField(type=KTI1, _d="Kontoverbindung international") + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_number = DataElementField(type='num', max_length=5, _d="Kontoauszugsnummer") + statement_year = DataElementField(type='num', length=4, _d="Kontoauszugsjahr") + 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 HKEKA5(FinTS3Segment): + """Kontoauszug anfordern, version 5 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + account = DataElementGroupField(type=KTI1, _d="Kontoverbindung international") + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_number = DataElementField(type='num', max_length=5, _d="Kontoauszugsnummer") + statement_year = DataElementField(type='num', length=4, _d="Kontoauszugsjahr") + 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 HIEKA3(FinTS3Segment): + """Kontoauszug, version 3 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_period = DataElementGroupField(type=ReportPeriod2, _d="Berichtszeitraum") + data = DataElementField(type='bin', _d="Gebuchte Umsätze") + statement_info = DataElementField(type='txt', max_length=65536, required=False, _d="Informationen zum Rechnungsabschluss") + customer_info = DataElementField(type='txt', max_length=65536, required=False, + _d="Informationen zu Kundenbedingungen") + advertising_text = DataElementField(type='txt', max_length=65536, required=False, _d="Werbetext") + account_iban = DataElementField(type='an', max_length=34, required=False, _d="IBAN Konto") + account_bic = DataElementField(type='an', max_length=11, required=False, _d="BIC Konto") + statement_name_1 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 1") + statement_name_2 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 2") + statement_name_extra = DataElementField(type='an', max_length=35, required=False, _d="Namenszusatz") + confirmation_code = DataElementField(type='bin', required=False, _d="Quittungscode") + + +class HIEKA4(FinTS3Segment): + """Kontoauszug, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_period = DataElementGroupField(type=ReportPeriod2, _d="Berichtszeitraum") + data = DataElementField(type='bin', _d="Gebuchte Umsätze") + statement_info = DataElementField(type='txt', max_length=65536, required=False, _d="Informationen zum Rechnungsabschluss") + customer_info = DataElementField(type='txt', max_length=65536, required=False, + _d="Informationen zu Kundenbedingungen") + advertising_text = DataElementField(type='txt', max_length=65536, required=False, _d="Werbetext") + account_iban = DataElementField(type='an', max_length=34, required=False, _d="IBAN Konto") + account_bic = DataElementField(type='an', max_length=11, required=False, _d="BIC Konto") + statement_name_1 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 1") + statement_name_2 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 2") + statement_name_extra = DataElementField(type='an', max_length=35, required=False, _d="Namenszusatz") + confirmation_code = DataElementField(type='bin', required=False, _d="Quittungscode") + + +class HIEKA5(FinTS3Segment): + """Kontoauszug, version 5 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle""" + statement_format = CodeField(enum=StatementFormat, length=1, required=False, _d="Kontoauszugsformat") + statement_period = DataElementGroupField(type=ReportPeriod2, _d="Berichtszeitraum") + date_created = DataElementField(type='dat', required=False, _d="Erstellungsdatum Kontoauszug") + statement_year = DataElementField(type='num', length=4, required=False, _d="Kontoauszugsjahr") + statement_number = DataElementField(type='num', max_length=5, required=False, _d="Kontoauszugsnummer") + data = DataElementField(type='bin', _d="Gebuchte Umsätze") + statement_info = DataElementField(type='txt', max_length=65536, required=False, _d="Informationen zum Rechnungsabschluss") + customer_info = DataElementField(type='txt', max_length=65536, required=False, + _d="Informationen zu Kundenbedingungen") + advertising_text = DataElementField(type='txt', max_length=65536, required=False, _d="Werbetext") + account_iban = DataElementField(type='an', max_length=34, required=False, _d="IBAN Konto") + account_bic = DataElementField(type='an', max_length=11, required=False, _d="BIC Konto") + statement_name_1 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 1") + statement_name_2 = DataElementField(type='an', max_length=35, required=False, _d="Auszugsname 2") + statement_name_extra = DataElementField(type='an', max_length=35, required=False, _d="Namenszusatz") + confirmation_code = DataElementField(type='bin', required=False, _d="Quittungscode")