diff --git a/crud.py b/crud.py index 74f04d2..cef3171 100644 --- a/crud.py +++ b/crud.py @@ -236,19 +236,49 @@ async def get_all_journal_entries(limit: int = 100) -> list[JournalEntry]: async def get_journal_entries_by_user( user_id: str, limit: int = 100 ) -> list[JournalEntry]: - entries = await db.fetchall( - """ - SELECT * FROM journal_entries - WHERE created_by = :user_id - ORDER BY entry_date DESC, created_at DESC - LIMIT :limit - """, - {"user_id": user_id, "limit": limit}, - JournalEntry, + """Get journal entries that affect the user's accounts""" + # Get all user-specific accounts + user_accounts = await db.fetchall( + "SELECT id FROM accounts WHERE user_id = :user_id", + {"user_id": user_id}, ) - for entry in entries: + if not user_accounts: + return [] + + account_ids = [acc["id"] for acc in user_accounts] + + # Get all journal entries that have lines affecting these accounts + # Build the IN clause with named parameters + placeholders = ','.join([f":account_{i}" for i in range(len(account_ids))]) + params = {f"account_{i}": acc_id for i, acc_id in enumerate(account_ids)} + params["limit"] = limit + + entries_data = await db.fetchall( + f""" + SELECT DISTINCT je.* + FROM journal_entries je + JOIN entry_lines el ON je.id = el.journal_entry_id + WHERE el.account_id IN ({placeholders}) + ORDER BY je.entry_date DESC, je.created_at DESC + LIMIT :limit + """, + params, + ) + + entries = [] + for entry_data in entries_data: + entry = JournalEntry( + id=entry_data["id"], + description=entry_data["description"], + entry_date=entry_data["entry_date"], + created_by=entry_data["created_by"], + created_at=entry_data["created_at"], + reference=entry_data["reference"], + lines=[], + ) entry.lines = await get_entry_lines(entry.id) + entries.append(entry) return entries diff --git a/static/js/index.js b/static/js/index.js index 6876513..ba27c0c 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -520,6 +520,17 @@ window.app = Vue.createApp({ getTotalAmount(entry) { if (!entry.lines || entry.lines.length === 0) return 0 return entry.lines.reduce((sum, line) => sum + line.debit + line.credit, 0) / 2 + }, + getEntryFiatAmount(entry) { + // Extract fiat amount from metadata if available + if (!entry.lines || entry.lines.length === 0) return null + + for (const line of entry.lines) { + if (line.metadata && line.metadata.fiat_currency && line.metadata.fiat_amount) { + return this.formatFiat(line.metadata.fiat_amount, line.metadata.fiat_currency) + } + } + return null } }, async created() { diff --git a/templates/castle/index.html b/templates/castle/index.html index 0ac63bc..b9b0c50 100644 --- a/templates/castle/index.html +++ b/templates/castle/index.html @@ -204,9 +204,15 @@ {% raw %}{{ formatDate(entry.entry_date) }}{% endraw %} + + Ref: {% raw %}{{ entry.reference }}{% endraw %} + {% raw %}{{ formatSats(getTotalAmount(entry)) }} sats{% endraw %} + + {% raw %}{{ getEntryFiatAmount(entry) }}{% endraw %} + diff --git a/views_api.py b/views_api.py index 83db451..a588639 100644 --- a/views_api.py +++ b/views_api.py @@ -157,8 +157,8 @@ async def api_get_user_entries( wallet: WalletTypeInfo = Depends(require_invoice_key), limit: int = 100, ) -> list[JournalEntry]: - """Get journal entries created by the current user""" - return await get_journal_entries_by_user(wallet.wallet.id, limit) + """Get journal entries that affect the current user's accounts""" + return await get_journal_entries_by_user(wallet.wallet.user, limit) @castle_api_router.get("/api/v1/entries/{entry_id}")