|
|
|
@ -5,7 +5,7 @@ from twisted.internet.task import LoopingCall
|
|
|
|
|
import requests
|
|
|
|
|
from simplejson.errors import JSONDecodeError
|
|
|
|
|
from json import dumps, loads
|
|
|
|
|
from lib.serde.nordigen import TXRoot, AccessToken, Institutions, Agreement, Requisitions, AccountDetails
|
|
|
|
|
from lib.serde.nordigen import TXRoot, AccessToken, Institutions, Agreement, Requisitions, AccountDetails, AccountBalancesRoot
|
|
|
|
|
from serde import ValidationError
|
|
|
|
|
|
|
|
|
|
# Project imports
|
|
|
|
@ -242,9 +242,6 @@ class Nordigen(util.Base):
|
|
|
|
|
continue
|
|
|
|
|
accounts = self.get_accounts(req["id"])
|
|
|
|
|
for account_id in accounts:
|
|
|
|
|
# if not account_id in self.banks:
|
|
|
|
|
# print("account_id", account_id, "not in self.banks!")
|
|
|
|
|
# continue
|
|
|
|
|
account_info = self.get_account(account_id)
|
|
|
|
|
if not account_info:
|
|
|
|
|
continue
|
|
|
|
@ -281,7 +278,55 @@ class Nordigen(util.Base):
|
|
|
|
|
headers = {"accept": "application/json", "Authorization": f"Bearer {self.token}"}
|
|
|
|
|
path = f"{settings.Nordigen.Base}/accounts/{account_id}/transactions/"
|
|
|
|
|
r = requests.get(path, headers=headers)
|
|
|
|
|
obj = TXRoot.from_json(r.content)
|
|
|
|
|
try:
|
|
|
|
|
obj = TXRoot.from_json(r.content)
|
|
|
|
|
except ValidationError as err:
|
|
|
|
|
self.log.error(f"Validation error: {err}")
|
|
|
|
|
return
|
|
|
|
|
parsed = obj.to_dict()["transactions"]["booked"]
|
|
|
|
|
self.normalise_transactions(parsed)
|
|
|
|
|
return parsed
|
|
|
|
|
|
|
|
|
|
def get_balance(self, account_id):
|
|
|
|
|
"""
|
|
|
|
|
Get the balance and currency of an account.
|
|
|
|
|
:param account_id: the account ID
|
|
|
|
|
:return: tuple of (currency, amount)
|
|
|
|
|
:rtype: tuple
|
|
|
|
|
"""
|
|
|
|
|
headers = {"accept": "application/json", "Authorization": f"Bearer {self.token}"}
|
|
|
|
|
path = f"{settings.Nordigen.Base}/accounts/{account_id}/balances/"
|
|
|
|
|
r = requests.get(path, headers=headers)
|
|
|
|
|
try:
|
|
|
|
|
obj = AccountBalancesRoot.from_json(r.content)
|
|
|
|
|
except ValidationError as err:
|
|
|
|
|
self.log.error(f"Validation error: {err}")
|
|
|
|
|
return
|
|
|
|
|
parsed = obj.to_dict()["balances"]
|
|
|
|
|
total = 0
|
|
|
|
|
currency = None
|
|
|
|
|
for entry in parsed:
|
|
|
|
|
if currency:
|
|
|
|
|
if not currency == entry["balanceAmount"]["currency"]:
|
|
|
|
|
self.log.error("Different currencies in balance query.")
|
|
|
|
|
return
|
|
|
|
|
total += float(entry["balanceAmount"]["amount"])
|
|
|
|
|
currency = entry["balanceAmount"]["currency"]
|
|
|
|
|
return (currency, total)
|
|
|
|
|
|
|
|
|
|
def get_total_map(self):
|
|
|
|
|
"""
|
|
|
|
|
Return a dictionary keyed by currencies with the amounts as values.
|
|
|
|
|
:return: dict keyed by currency, values are amounts
|
|
|
|
|
:rtype: dict
|
|
|
|
|
"""
|
|
|
|
|
totals = {}
|
|
|
|
|
for account_id in self.banks:
|
|
|
|
|
currency, amount = self.get_balance(account_id)
|
|
|
|
|
if not amount:
|
|
|
|
|
continue
|
|
|
|
|
if currency in totals:
|
|
|
|
|
totals[currency] += amount
|
|
|
|
|
else:
|
|
|
|
|
totals[currency] = amount
|
|
|
|
|
return totals
|
|
|
|
|