diff --git a/fava_client.py b/fava_client.py index 0fb28b5..e87ddeb 100644 --- a/fava_client.py +++ b/fava_client.py @@ -172,18 +172,18 @@ class FavaClient: async def get_user_balance(self, user_id: str) -> Dict[str, Any]: """ - Get user's total balance (what castle owes user). + Get user's balance from castle's perspective. Aggregates: - - Liabilities:Payable:User-{user_id} (negative balance = castle owes) - - Assets:Receivable:User-{user_id} (positive balance = user owes) + - Liabilities:Payable:User-{user_id} (negative = castle owes user) + - Assets:Receivable:User-{user_id} (positive = user owes castle) Args: user_id: User ID Returns: { - "balance": int (sats, positive = castle owes user), + "balance": int (sats, positive = user owes castle, negative = castle owes user), "fiat_balances": {"EUR": Decimal("100.50")}, "accounts": [list of account dicts with balances] } @@ -228,12 +228,11 @@ class FavaClient: for cost_str, amount in sats_positions.items(): amount_int = int(amount) - # For user balance perspective, negate Beancount balance - # - Payable (Liability): negative in Beancount → positive (castle owes user) - # - Receivable (Asset): positive in Beancount → negative (user owes castle) - adjusted_amount = -amount_int - total_sats += adjusted_amount - account_balance["sats"] += adjusted_amount + # Use Beancount balance as-is (castle's perspective) + # - Receivable (Asset): positive = user owes castle + # - Payable (Liability): negative = castle owes user + total_sats += amount_int + account_balance["sats"] += amount_int # Extract fiat amount from cost basis # Format: "100.00 EUR" or "{100.00 EUR}" @@ -248,22 +247,19 @@ class FavaClient: if fiat_currency not in fiat_balances: fiat_balances[fiat_currency] = Decimal(0) - # Apply same sign adjustment to fiat - # Cost basis is always positive, derive sign from amount + # Apply same sign as sats amount if amount_int < 0: fiat_amount = -fiat_amount - adjusted_fiat = -fiat_amount - fiat_balances[fiat_currency] += adjusted_fiat + fiat_balances[fiat_currency] += fiat_amount except (ValueError, IndexError): logger.warning(f"Could not parse cost basis: {cost_str}") elif isinstance(sats_positions, (int, float)): # Simple number (no cost basis) amount_int = int(sats_positions) - # Negate Beancount balance for user perspective - adjusted_amount = -amount_int - total_sats += adjusted_amount - account_balance["sats"] += adjusted_amount + # Use Beancount balance as-is + total_sats += amount_int + account_balance["sats"] += amount_int accounts.append(account_balance) @@ -341,31 +337,33 @@ class FavaClient: continue import re - # Extract SATS amount + # Extract SATS amount (with sign) sats_match = re.match(r'^(-?\d+)\s+SATS', amount_str) if sats_match: sats_amount = int(sats_match.group(1)) - # Negate Beancount balance for user perspective - # Payable (liability): negative in Beancount = castle owes user (positive for user) - # Receivable (asset): positive in Beancount = user owes castle (negative for user) - adjusted_amount = -sats_amount - user_data[user_id]["balance"] += adjusted_amount + # For admin/castle view, use Beancount amounts as-is: + # Receivable (asset): positive in Beancount = user owes castle (positive) + # Payable (liability): negative in Beancount = castle owes user (negative) + user_data[user_id]["balance"] += sats_amount # Extract fiat from cost syntax: {33.33 EUR, ...} cost_match = re.search(r'\{([\d.]+)\s+([A-Z]+)', amount_str) if cost_match: - fiat_amount_raw = Decimal(cost_match.group(1)) + fiat_amount_unsigned = Decimal(cost_match.group(1)) fiat_currency = cost_match.group(2) if fiat_currency not in user_data[user_id]["fiat_balances"]: user_data[user_id]["fiat_balances"][fiat_currency] = Decimal(0) - # Apply same sign logic as sats - if "-" in amount_str: - fiat_amount_raw = -fiat_amount_raw - adjusted_fiat = -fiat_amount_raw - user_data[user_id]["fiat_balances"][fiat_currency] += adjusted_fiat + # Apply the same sign as the SATS amount + # If SATS is negative, fiat should be negative too + if sats_match: + sats_amount_for_sign = int(sats_match.group(1)) + if sats_amount_for_sign < 0: + fiat_amount_unsigned = -fiat_amount_unsigned + + user_data[user_id]["fiat_balances"][fiat_currency] += fiat_amount_unsigned return list(user_data.values()) diff --git a/templates/castle/index.html b/templates/castle/index.html index bd33114..6aff4f5 100644 --- a/templates/castle/index.html +++ b/templates/castle/index.html @@ -182,7 +182,7 @@