Update get_account_balance to use sum(weight) for SATS
Replace sum(position) with sum(weight) for efficient SATS aggregation from price notation. Also return fiat amount from sum(number). This simplifies the parsing logic and provides consistent SATS totals across all BQL-based balance methods. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
048d19f90b
commit
49d18c3e73
2 changed files with 27 additions and 22 deletions
|
|
@ -111,13 +111,16 @@ class FavaClient:
|
|||
"""
|
||||
Get balance for a specific account (excluding pending transactions).
|
||||
|
||||
Uses sum(weight) for efficient SATS aggregation from price notation.
|
||||
|
||||
Args:
|
||||
account_name: Full account name (e.g., "Assets:Receivable:User-abc123")
|
||||
|
||||
Returns:
|
||||
Dict with:
|
||||
- sats: int (balance in satoshis)
|
||||
- positions: dict (currency → amount with cost basis)
|
||||
- sats: int (balance in satoshis from weight column)
|
||||
- fiat: Decimal (balance in fiat currency from number column)
|
||||
- fiat_currency: str (currency code, defaults to EUR)
|
||||
|
||||
Note:
|
||||
Excludes pending transactions (flag='!') from balance calculation.
|
||||
|
|
@ -125,12 +128,13 @@ class FavaClient:
|
|||
|
||||
Example:
|
||||
balance = await fava_client.get_account_balance("Assets:Receivable:User-abc")
|
||||
# Returns: {
|
||||
# "sats": 200000,
|
||||
# "positions": {"SATS": {"{100.00 EUR}": 200000}}
|
||||
# }
|
||||
# Returns: {"sats": 200000, "fiat": Decimal("150.00"), "fiat_currency": "EUR"}
|
||||
"""
|
||||
query = f"SELECT sum(position) WHERE account = '{account_name}' AND flag != '!'"
|
||||
from decimal import Decimal
|
||||
|
||||
# Use sum(weight) for SATS and sum(number) for fiat
|
||||
# Note: BQL doesn't support != operator, so use flag = '*' to exclude pending
|
||||
query = f"SELECT sum(number), sum(weight) WHERE account = '{account_name}' AND flag = '*'"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
|
|
@ -141,26 +145,26 @@ class FavaClient:
|
|||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
if not data['data']['rows']:
|
||||
return {"sats": 0, "positions": {}}
|
||||
if not data['data']['rows'] or not data['data']['rows'][0]:
|
||||
return {"sats": 0, "fiat": Decimal(0), "fiat_currency": "EUR"}
|
||||
|
||||
# Fava returns: [[account, {"SATS": {cost: amount}}]]
|
||||
positions = data['data']['rows'][0][1] if data['data']['rows'] else {}
|
||||
row = data['data']['rows'][0]
|
||||
fiat_sum = row[0] if len(row) > 0 else 0
|
||||
weight_sum = row[1] if len(row) > 1 else {}
|
||||
|
||||
# Sum up all SATS positions
|
||||
# Parse fiat amount
|
||||
fiat_amount = Decimal(str(fiat_sum)) if fiat_sum else Decimal(0)
|
||||
|
||||
# Parse SATS from weight column
|
||||
total_sats = 0
|
||||
if isinstance(positions, dict) and "SATS" in positions:
|
||||
sats_positions = positions["SATS"]
|
||||
if isinstance(sats_positions, dict):
|
||||
# Sum all amounts (with different cost bases)
|
||||
total_sats = sum(int(amount) for amount in sats_positions.values())
|
||||
elif isinstance(sats_positions, (int, float)):
|
||||
# Simple number (no cost basis)
|
||||
total_sats = int(sats_positions)
|
||||
if isinstance(weight_sum, dict) and "SATS" in weight_sum:
|
||||
sats_value = weight_sum["SATS"]
|
||||
total_sats = int(Decimal(str(sats_value)))
|
||||
|
||||
return {
|
||||
"sats": total_sats,
|
||||
"positions": positions
|
||||
"fiat": fiat_amount,
|
||||
"fiat_currency": "EUR" # Default, could be extended to detect currency
|
||||
}
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue