Adds fiat currency balances to user balances

Extends user balance information to include fiat currency balances,
calculated based on entry line metadata and account types.

This allows for a more comprehensive view of user balances,
including both satoshi and fiat currency holdings.

Updates the castle index template and API to display fiat balances.
This commit is contained in:
padreug 2025-10-22 16:56:13 +02:00
parent be386f60ef
commit b0705fc24a
5 changed files with 116 additions and 4 deletions

76
crud.py
View file

@ -298,10 +298,43 @@ async def get_user_balance(user_id: str) -> UserBalance:
)
total_balance = 0
fiat_balances = {} # Track fiat balances by currency
for account in user_accounts:
balance = await get_account_balance(account.id)
# Get all entry lines for this account to calculate fiat balances
entry_lines = await db.fetchall(
"SELECT * FROM entry_lines WHERE account_id = :account_id",
{"account_id": account.id},
)
for line in entry_lines:
# Parse metadata to get fiat amounts
metadata = json.loads(line["metadata"]) if line.get("metadata") else {}
fiat_currency = metadata.get("fiat_currency")
fiat_amount = metadata.get("fiat_amount")
if fiat_currency and fiat_amount:
# Initialize currency if not exists
if fiat_currency not in fiat_balances:
fiat_balances[fiat_currency] = 0.0
# Calculate fiat balance based on account type
if account.account_type == AccountType.LIABILITY:
# Liability: credit increases (castle owes more), debit decreases
if line["credit"] > 0:
fiat_balances[fiat_currency] += fiat_amount
elif line["debit"] > 0:
fiat_balances[fiat_currency] -= fiat_amount
elif account.account_type == AccountType.ASSET:
# Asset (receivable): debit increases (user owes more), credit decreases
if line["debit"] > 0:
fiat_balances[fiat_currency] -= fiat_amount
elif line["credit"] > 0:
fiat_balances[fiat_currency] += fiat_amount
# Calculate satoshi balance
# If it's a liability account (castle owes user), it's positive
# If it's an asset account (user owes castle), it's negative
if account.account_type == AccountType.LIABILITY:
@ -314,6 +347,7 @@ async def get_user_balance(user_id: str) -> UserBalance:
user_id=user_id,
balance=total_balance,
accounts=user_accounts,
fiat_balances=fiat_balances,
)
@ -337,17 +371,55 @@ async def get_all_user_balances() -> list[UserBalance]:
user_balances = []
for user_id, accounts in users_dict.items():
total_balance = 0
fiat_balances = {}
for account in accounts:
balance = await get_account_balance(account.id)
# Get all entry lines for this account to calculate fiat balances
entry_lines = await db.fetchall(
"SELECT * FROM entry_lines WHERE account_id = :account_id",
{"account_id": account.id},
)
for line in entry_lines:
# Parse metadata to get fiat amounts
metadata = json.loads(line["metadata"]) if line.get("metadata") else {}
fiat_currency = metadata.get("fiat_currency")
fiat_amount = metadata.get("fiat_amount")
if fiat_currency and fiat_amount:
# Initialize currency if not exists
if fiat_currency not in fiat_balances:
fiat_balances[fiat_currency] = 0.0
# Calculate fiat balance based on account type
if account.account_type == AccountType.LIABILITY:
# Liability: credit increases (castle owes more), debit decreases
if line["credit"] > 0:
fiat_balances[fiat_currency] += fiat_amount
elif line["debit"] > 0:
fiat_balances[fiat_currency] -= fiat_amount
elif account.account_type == AccountType.ASSET:
# Asset (receivable): debit increases (user owes more), credit decreases
if line["debit"] > 0:
fiat_balances[fiat_currency] -= fiat_amount
elif line["credit"] > 0:
fiat_balances[fiat_currency] += fiat_amount
# Calculate satoshi balance
if account.account_type == AccountType.LIABILITY:
total_balance += balance
elif account.account_type == AccountType.ASSET:
total_balance -= balance
if total_balance != 0: # Only include users with non-zero balance
if total_balance != 0 or fiat_balances: # Include users with non-zero balance or fiat balances
user_balances.append(
UserBalance(
user_id=user_id, balance=total_balance, accounts=accounts
user_id=user_id,
balance=total_balance,
accounts=accounts,
fiat_balances=fiat_balances,
)
)