Implement viewing transactions for an account

This commit is contained in:
2023-03-09 20:24:46 +00:00
parent cfb7cec88f
commit ac483711c4
10 changed files with 396 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
from abc import ABC
from core.lib.db import convert, r
class AggregatorClient(ABC):
def store_account_info(self, account_infos):
@@ -40,3 +42,28 @@ class AggregatorClient(ABC):
self.instance.currencies = currencies
self.instance.save()
async def process_transactions(self, account_id, transactions):
if not transactions:
return False
transaction_ids = [x["transaction_id"] for x in transactions]
new_key_name = f"new.transactions.{self.instance.id}.{self.name}.{account_id}"
old_key_name = f"transactions.{self.instance.id}.{self.name}.{account_id}"
# for transaction_id in transaction_ids:
if not transaction_ids:
return
r.sadd(new_key_name, *transaction_ids)
difference = list(r.sdiff(new_key_name, old_key_name))
difference = convert(difference)
new_transactions = [
x for x in transactions if x["transaction_id"] in difference
]
# Rename the new key to the old key so we can run the diff again
r.rename(new_key_name, old_key_name)
for transaction in new_transactions:
transaction["subclass"] = self.name
# self.tx.transaction(transaction)

View File

@@ -1,7 +1,9 @@
from datetime import timedelta
from hashlib import sha256
from django.conf import settings
from django.utils import timezone
from orjson import dumps
from core.clients.aggregator import AggregatorClient
from core.clients.base import BaseClient
@@ -125,7 +127,7 @@ class NordigenClient(BaseClient, AggregatorClient):
async def get_account(self, account_id):
"""
Get details of an account.
:param requisition: requisition ID"""
:param account_id: account ID"""
path = f"accounts/{account_id}/details"
response = await self.call(path, schema="AccountDetails")
@@ -145,6 +147,7 @@ class NordigenClient(BaseClient, AggregatorClient):
parsed["recipient"] = "TODO"
# Let's add the account ID so we can reference it later
parsed["account_id"] = account_id
parsed["aggregator_id"] = str(self.instance.id)
return parsed
async def get_all_account_info(self, requisition=None, store=False):
@@ -243,3 +246,61 @@ class NordigenClient(BaseClient, AggregatorClient):
else:
totals[currency] = amount
return totals
def normalise_transactions(self, transactions):
for transaction in transactions:
# Rename ID
if "transactionId" in transaction:
transaction["transaction_id"] = transaction["transactionId"]
del transaction["transactionId"]
elif "internalTransactionId" in transaction:
transaction["transaction_id"] = transaction["internalTransactionId"]
del transaction["internalTransactionId"]
else:
# No transaction ID. This is a problem for our implementation
tx_hash = sha256(
dumps(transaction, sort_keys=True).encode("utf8")
).hexdigest()
transaction["transaction_id"] = tx_hash
# Rename timestamp
if "bookingDateTime" in transaction:
transaction["ts"] = transaction["bookingDateTime"]
del transaction["bookingDateTime"]
elif "bookingDate" in transaction:
transaction["ts"] = transaction["bookingDate"]
del transaction["bookingDate"]
transaction["amount"] = float(transaction["transactionAmount"]["amount"])
transaction["currency"] = transaction["transactionAmount"]["currency"]
del transaction["transactionAmount"]
if transaction["remittanceInformationUnstructuredArray"]:
ref_list = transaction["remittanceInformationUnstructuredArray"]
reference = "|".join(ref_list)
transaction["reference"] = reference
del transaction["remittanceInformationUnstructuredArray"]
elif transaction["remittanceInformationUnstructured"]:
reference = transaction["remittanceInformationUnstructured"]
transaction["reference"] = reference
del transaction["remittanceInformationUnstructured"]
else:
raise Exception(f"No way to get reference: {transaction}")
async def get_transactions(self, account_id, process=False):
"""
Get all transactions for an account.
:param account_id: account to fetch transactions for
:return: list of transactions
:rtype: dict
"""
path = f"accounts/{account_id}/transactions"
response = await self.call(path, schema="Transactions")
parsed = response["booked"]
self.normalise_transactions(parsed)
if process:
await self.process_transactions(parsed)
return parsed