Refactors expense tracking to use fiat amounts
Updates the expense tracking system to store payables and receivables in fiat currency within Beancount. This ensures accurate debt representation and simplifies balance calculations. Changes include: - Converting `format_expense_entry` and `format_receivable_entry` to use fiat amounts. - Introducing `format_net_settlement_entry` for net settlement payments. - Modifying `format_payment_entry` to use cost syntax for fiat tracking. - Adjusting Fava client to correctly process new amount formats and metadata. - Adding average cost basis posting format The use of fiat amounts and cost basis aims to provide better accuracy and compatibility with existing Beancount workflows.
This commit is contained in:
parent
8396331d5a
commit
ca2ce1dfcc
3 changed files with 372 additions and 123 deletions
52
tasks.py
52
tasks.py
|
|
@ -175,7 +175,7 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
from decimal import Decimal
|
||||
from .crud import get_account_by_name, get_or_create_user_account
|
||||
from .models import AccountType
|
||||
from .beancount_format import format_payment_entry
|
||||
from .beancount_format import format_net_settlement_entry
|
||||
|
||||
# Convert amount from millisatoshis to satoshis
|
||||
amount_sats = payment.amount // 1000
|
||||
|
|
@ -191,30 +191,58 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
if fiat_amount_str:
|
||||
fiat_amount = Decimal(str(fiat_amount_str))
|
||||
|
||||
if not fiat_currency or not fiat_amount:
|
||||
logger.error(f"Payment {payment.payment_hash} missing fiat currency/amount metadata")
|
||||
return
|
||||
|
||||
logger.info(f"Final fiat values for payment entry - currency: {fiat_currency}, amount: {fiat_amount}")
|
||||
|
||||
# Get user's receivable account (what user owes)
|
||||
# Get user's current balance to determine receivables and payables
|
||||
balance = await fava.get_user_balance(user_id)
|
||||
fiat_balances = balance.get("fiat_balances", {})
|
||||
total_fiat_balance = fiat_balances.get(fiat_currency, Decimal(0))
|
||||
|
||||
logger.info(f"User {user_id[:8]} current balance: {total_fiat_balance} {fiat_currency}")
|
||||
|
||||
# Determine receivables and payables based on balance
|
||||
# Positive balance = user owes castle (receivable)
|
||||
# Negative balance = castle owes user (payable)
|
||||
if total_fiat_balance > 0:
|
||||
# User owes castle
|
||||
total_receivable = total_fiat_balance
|
||||
total_payable = Decimal(0)
|
||||
else:
|
||||
# Castle owes user
|
||||
total_receivable = Decimal(0)
|
||||
total_payable = abs(total_fiat_balance)
|
||||
|
||||
logger.info(f"Settlement amounts - Receivable: {total_receivable}, Payable: {total_payable}, Net: {fiat_amount}")
|
||||
|
||||
# Get account names
|
||||
user_receivable = await get_or_create_user_account(
|
||||
user_id, AccountType.ASSET, "Accounts Receivable"
|
||||
)
|
||||
|
||||
# Get lightning account
|
||||
user_payable = await get_or_create_user_account(
|
||||
user_id, AccountType.LIABILITY, "Accounts Payable"
|
||||
)
|
||||
lightning_account = await get_account_by_name("Assets:Bitcoin:Lightning")
|
||||
if not lightning_account:
|
||||
logger.error("Lightning account 'Assets:Bitcoin:Lightning' not found")
|
||||
return
|
||||
|
||||
# Format as Beancount transaction
|
||||
entry = format_payment_entry(
|
||||
# Format as net settlement transaction
|
||||
entry = format_net_settlement_entry(
|
||||
user_id=user_id,
|
||||
payment_account=lightning_account.name, # "Assets:Bitcoin:Lightning"
|
||||
payable_or_receivable_account=user_receivable.name, # "Assets:Receivable:User-{id}"
|
||||
payment_account=lightning_account.name,
|
||||
receivable_account=user_receivable.name,
|
||||
payable_account=user_payable.name,
|
||||
amount_sats=amount_sats,
|
||||
description=f"Lightning payment from user {user_id[:8]}",
|
||||
entry_date=datetime.now().date(),
|
||||
is_payable=False, # User paying castle (receivable settlement)
|
||||
net_fiat_amount=fiat_amount,
|
||||
total_receivable_fiat=total_receivable,
|
||||
total_payable_fiat=total_payable,
|
||||
fiat_currency=fiat_currency,
|
||||
fiat_amount=fiat_amount,
|
||||
description=f"Lightning payment settlement from user {user_id[:8]}",
|
||||
entry_date=datetime.now().date(),
|
||||
payment_hash=payment.payment_hash,
|
||||
reference=payment.payment_hash
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue