Make Nordigen and TrueLayer compatible with Transactions

This commit is contained in:
Mark Veidemanis 2022-03-25 18:46:08 +00:00
parent b3a39401b5
commit 2f9fb31baf
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
4 changed files with 38 additions and 11 deletions

View File

@ -33,12 +33,12 @@ class Sinks(util.Base):
self.truelayer = sinks.truelayer.TrueLayer(self) self.truelayer = sinks.truelayer.TrueLayer(self)
# setattr(self.truelayer, "sinks", self) # setattr(self.truelayer, "sinks", self)
def got_transactions(self, bank, account_id, transactions): def got_transactions(self, subclass, account_id, transactions):
if not transactions: if not transactions:
return False return False
transaction_ids = [x["transaction_id"] for x in transactions] transaction_ids = [x["transaction_id"] for x in transactions]
new_key_name = f"new.transactions.{bank}.{account_id}" new_key_name = f"new.transactions.{subclass}.{account_id}"
old_key_name = f"transactions.{bank}.{account_id}" old_key_name = f"transactions.{subclass}.{account_id}"
# for transaction_id in transaction_ids: # for transaction_id in transaction_ids:
if not transaction_ids: if not transaction_ids:
return return
@ -53,6 +53,7 @@ class Sinks(util.Base):
# Rename the new key to the old key so we can run the diff again # Rename the new key to the old key so we can run the diff again
r.rename(new_key_name, old_key_name) r.rename(new_key_name, old_key_name)
for transaction in new_transactions: for transaction in new_transactions:
transaction["subclass"] = subclass
self.tx.transaction(transaction) self.tx.transaction(transaction)
def got_account_info(self, subclass, account_infos): def got_account_info(self, subclass, account_infos):

View File

@ -45,6 +45,14 @@ class Nordigen(util.Base):
self.sinks.got_account_info("nordigen", account_infos) self.sinks.got_account_info("nordigen", account_infos)
self.lc_tx = LoopingCall(self.transaction_loop)
self.lc_tx.start(int(settings.Nordigen.RefreshSec))
def transaction_loop(self):
for account_id in self.banks:
transactions = self.get_transactions(account_id)
self.sinks.got_transactions("nordigen", account_id, transactions)
def get_access_token(self): def get_access_token(self):
""" """
Get an access token. Get an access token.
@ -246,6 +254,23 @@ class Nordigen(util.Base):
to_return[req["institution_id"]] = [account_info] to_return[req["institution_id"]] = [account_info]
return to_return return to_return
def normalise_transactions(self, transactions):
for transaction in transactions:
# Rename ID
transaction["transaction_id"] = transaction["transactionId"]
del transaction["transactionId"]
# Rename timestamp
transaction["timestamp"] = transaction["bookingDate"]
del transaction["bookingDate"]
transaction["amount"] = float(transaction["transactionAmount"]["amount"])
transaction["currency"] = transaction["transactionAmount"]["currency"]
del transaction["transactionAmount"]
transaction["reference"] = transaction["remittanceInformationUnstructured"]
del transaction["remittanceInformationUnstructured"]
def get_transactions(self, account_id): def get_transactions(self, account_id):
""" """
Get all transactions for an account. Get all transactions for an account.
@ -257,4 +282,6 @@ class Nordigen(util.Base):
path = f"{settings.Nordigen.Base}/accounts/{account_id}/transactions/" path = f"{settings.Nordigen.Base}/accounts/{account_id}/transactions/"
r = requests.get(path, headers=headers) r = requests.get(path, headers=headers)
obj = TXRoot.from_json(r.content) obj = TXRoot.from_json(r.content)
return obj.to_dict()["transactions"]["booked"] parsed = obj.to_dict()["transactions"]["booked"]
self.normalise_transactions(parsed)
return parsed

View File

@ -54,7 +54,7 @@ class TrueLayer(util.Base):
for account_id in self.banks[bank]: for account_id in self.banks[bank]:
# account_data = self.get_account(bank, account_id) # account_data = self.get_account(bank, account_id)
transactions = self.get_transactions(bank, account_id) transactions = self.get_transactions(bank, account_id)
self.sinks.got_transactions(bank, account_id, transactions) self.sinks.got_transactions("truelayer", account_id, transactions)
def add_refresh_token(self, refresh_token): def add_refresh_token(self, refresh_token):
""" """

View File

@ -77,7 +77,6 @@ class Transactions(util.Base):
""" """
ts = data["timestamp"] ts = data["timestamp"]
txid = data["transaction_id"] txid = data["transaction_id"]
txtype = data["transaction_type"]
if "amount" not in data: if "amount" not in data:
return return
if "currency" not in data: if "currency" not in data:
@ -87,27 +86,27 @@ class Transactions(util.Base):
self.log.info(f"Ignoring transaction with negative/zero amount: {txid}") self.log.info(f"Ignoring transaction with negative/zero amount: {txid}")
return return
currency = data["currency"] currency = data["currency"]
description = data["description"]
if "meta" in data: if "meta" in data:
if "provider_reference" in data["meta"]: if "provider_reference" in data["meta"]:
reference = data["meta"]["provider_reference"] reference = data["meta"]["provider_reference"]
else: else:
reference = "not_set" reference = "not_set"
elif "reference" in data:
reference = data["reference"]
else: else:
reference = "not_set" reference = "not_set"
subclass = data["subclass"]
to_store = { to_store = {
"trade_id": "", "trade_id": "",
"subclass": subclass,
"ts": ts, "ts": ts,
"txid": txid, "txid": txid,
"txtype": txtype,
"reference": reference, "reference": reference,
"amount": amount, "amount": amount,
"currency": currency, "currency": currency,
"description": description,
} }
self.log.info(f"Transaction processed: {dumps(to_store, indent=2)}") self.log.info(f"Transaction processed: {dumps(to_store, indent=2)}")
self.irc.sendmsg(f"AUTO Incoming transaction: {amount}{currency} ({reference}) - {description}") self.irc.sendmsg(f"AUTO Incoming transaction on {subclass}: {amount}{currency} ({reference})")
# Partial reference implementation # Partial reference implementation
# Account for silly people not removing the default string # Account for silly people not removing the default string
# Split the reference into parts # Split the reference into parts