Adds pagination to transaction history

Implements pagination for the transaction history, enabling users
to navigate through their transactions in manageable chunks. This
improves performance and user experience, especially for users
with a large number of transactions. It also introduces total entry counts.
This commit is contained in:
padreug 2025-11-08 23:51:12 +01:00
parent 4b327a0aab
commit 69b8f6e2d3
4 changed files with 120 additions and 12 deletions

48
crud.py
View file

@ -266,14 +266,14 @@ async def get_entry_lines(journal_entry_id: str) -> list[EntryLine]:
return lines
async def get_all_journal_entries(limit: int = 100) -> list[JournalEntry]:
async def get_all_journal_entries(limit: int = 100, offset: int = 0) -> list[JournalEntry]:
entries_data = await db.fetchall(
"""
SELECT * FROM journal_entries
ORDER BY entry_date DESC, created_at DESC
LIMIT :limit
LIMIT :limit OFFSET :offset
""",
{"limit": limit},
{"limit": limit, "offset": offset},
)
entries = []
@ -301,7 +301,7 @@ async def get_all_journal_entries(limit: int = 100) -> list[JournalEntry]:
async def get_journal_entries_by_user(
user_id: str, limit: int = 100
user_id: str, limit: int = 100, offset: int = 0
) -> list[JournalEntry]:
"""Get journal entries that affect the user's accounts"""
# Get all user-specific accounts
@ -320,6 +320,7 @@ async def get_journal_entries_by_user(
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
params["offset"] = offset
entries_data = await db.fetchall(
f"""
@ -328,7 +329,7 @@ async def get_journal_entries_by_user(
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
LIMIT :limit OFFSET :offset
""",
params,
)
@ -357,6 +358,43 @@ async def get_journal_entries_by_user(
return entries
async def count_all_journal_entries() -> int:
"""Count total number of journal entries"""
result = await db.fetchone(
"SELECT COUNT(*) as total FROM journal_entries"
)
return result["total"] if result else 0
async def count_journal_entries_by_user(user_id: str) -> int:
"""Count 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},
)
if not user_accounts:
return 0
account_ids = [acc["id"] for acc in user_accounts]
# Count journal entries that have lines affecting these accounts
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)}
result = await db.fetchone(
f"""
SELECT COUNT(DISTINCT je.id) as total
FROM journal_entries je
JOIN entry_lines el ON je.id = el.journal_entry_id
WHERE el.account_id IN ({placeholders})
""",
params,
)
return result["total"] if result else 0
# ===== BALANCE AND REPORTING =====