mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 02:07:09 +00:00
Allow fints config as fallback for account type (#75680)
This commit is contained in:
parent
3c48ce9ee7
commit
e1cf261379
@ -3,10 +3,12 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from functools import cached_property
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from fints.client import FinTS3PinTanClient
|
from fints.client import FinTS3PinTanClient
|
||||||
|
from fints.models import SEPAAccount
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||||
@ -77,7 +79,7 @@ def setup_platform(
|
|||||||
acc[CONF_ACCOUNT]: acc[CONF_NAME] for acc in config[CONF_HOLDINGS]
|
acc[CONF_ACCOUNT]: acc[CONF_NAME] for acc in config[CONF_HOLDINGS]
|
||||||
}
|
}
|
||||||
|
|
||||||
client = FinTsClient(credentials, fints_name)
|
client = FinTsClient(credentials, fints_name, account_config, holdings_config)
|
||||||
balance_accounts, holdings_accounts = client.detect_accounts()
|
balance_accounts, holdings_accounts = client.detect_accounts()
|
||||||
accounts: list[SensorEntity] = []
|
accounts: list[SensorEntity] = []
|
||||||
|
|
||||||
@ -115,21 +117,27 @@ class FinTsClient:
|
|||||||
Use this class as Context Manager to get the FinTS3Client object.
|
Use this class as Context Manager to get the FinTS3Client object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, credentials: BankCredentials, name: str) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
credentials: BankCredentials,
|
||||||
|
name: str,
|
||||||
|
account_config: dict,
|
||||||
|
holdings_config: dict,
|
||||||
|
) -> None:
|
||||||
"""Initialize a FinTsClient."""
|
"""Initialize a FinTsClient."""
|
||||||
self._credentials = credentials
|
self._credentials = credentials
|
||||||
|
self._account_information: dict[str, dict] = {}
|
||||||
|
self._account_information_fetched = False
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.account_config = account_config
|
||||||
|
self.holdings_config = holdings_config
|
||||||
|
|
||||||
@property
|
@cached_property
|
||||||
def client(self):
|
def client(self) -> FinTS3PinTanClient:
|
||||||
"""Get the client object.
|
"""Get the FinTS client object.
|
||||||
|
|
||||||
As the fints library is stateless, there is not benefit in caching
|
The FinTS library persists the current dialog with the bank
|
||||||
the client objects. If that ever changes, consider caching the client
|
and stores bank capabilities. So caching the client is beneficial.
|
||||||
object and also think about potential concurrency problems.
|
|
||||||
|
|
||||||
Note: As of version 2, the fints library is not stateless anymore.
|
|
||||||
This should be considered when reworking this integration.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return FinTS3PinTanClient(
|
return FinTS3PinTanClient(
|
||||||
@ -139,26 +147,77 @@ class FinTsClient:
|
|||||||
self._credentials.url,
|
self._credentials.url,
|
||||||
)
|
)
|
||||||
|
|
||||||
def detect_accounts(self):
|
def get_account_information(self, iban: str) -> dict | None:
|
||||||
"""Identify the accounts of the bank."""
|
"""Get a dictionary of account IBANs as key and account information as value."""
|
||||||
|
|
||||||
bank = self.client
|
if not self._account_information_fetched:
|
||||||
accounts = bank.get_sepa_accounts()
|
self._account_information = {
|
||||||
account_types = {
|
account["iban"]: account
|
||||||
x["iban"]: x["type"]
|
for account in self.client.get_information()["accounts"]
|
||||||
for x in bank.get_information()["accounts"]
|
}
|
||||||
if x["iban"] is not None
|
self._account_information_fetched = True
|
||||||
}
|
|
||||||
|
return self._account_information.get(iban, None)
|
||||||
|
|
||||||
|
def is_balance_account(self, account: SEPAAccount) -> bool:
|
||||||
|
"""Determine if the given account is of type balance account."""
|
||||||
|
if not account.iban:
|
||||||
|
return False
|
||||||
|
|
||||||
|
account_information = self.get_account_information(account.iban)
|
||||||
|
if not account_information:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not account_information["type"]:
|
||||||
|
# bank does not support account types, use value from config
|
||||||
|
if (
|
||||||
|
account_information["iban"] in self.account_config
|
||||||
|
or account_information["account_number"] in self.account_config
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
elif 1 <= account_information["type"] <= 9:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_holdings_account(self, account: SEPAAccount) -> bool:
|
||||||
|
"""Determine if the given account of type holdings account."""
|
||||||
|
if not account.iban:
|
||||||
|
return False
|
||||||
|
|
||||||
|
account_information = self.get_account_information(account.iban)
|
||||||
|
if not account_information:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not account_information["type"]:
|
||||||
|
# bank does not support account types, use value from config
|
||||||
|
if (
|
||||||
|
account_information["iban"] in self.holdings_config
|
||||||
|
or account_information["account_number"] in self.holdings_config
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
elif 30 <= account_information["type"] <= 39:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def detect_accounts(self) -> tuple[list, list]:
|
||||||
|
"""Identify the accounts of the bank."""
|
||||||
|
|
||||||
balance_accounts = []
|
balance_accounts = []
|
||||||
holdings_accounts = []
|
holdings_accounts = []
|
||||||
for account in accounts:
|
|
||||||
account_type = account_types[account.iban]
|
for account in self.client.get_sepa_accounts():
|
||||||
if 1 <= account_type <= 9: # 1-9 is balance account
|
|
||||||
|
if self.is_balance_account(account):
|
||||||
balance_accounts.append(account)
|
balance_accounts.append(account)
|
||||||
elif 30 <= account_type <= 39: # 30-39 is holdings account
|
|
||||||
|
elif self.is_holdings_account(account):
|
||||||
holdings_accounts.append(account)
|
holdings_accounts.append(account)
|
||||||
|
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Could not determine type of account %s", account.iban)
|
||||||
|
|
||||||
return balance_accounts, holdings_accounts
|
return balance_accounts, holdings_accounts
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user