Adds custom date range filtering to transactions

Enables users to filter transactions by a custom date range, providing more flexibility in viewing transaction history.

Prioritizes custom date range over preset days for filtering.

Displays a warning if a user attempts to apply a custom date range without selecting both start and end dates.
This commit is contained in:
Padreug 2025-12-14 12:47:23 +01:00
parent f2df2f543b
commit 1d2eb05c36
4 changed files with 162 additions and 23 deletions

View file

@ -855,13 +855,25 @@ class FavaClient:
logger.error(f"Failed to fetch accounts via BQL: {e}")
raise
async def get_journal_entries(self, days: int = None) -> List[Dict[str, Any]]:
async def get_journal_entries(
self,
days: int = None,
start_date: str = None,
end_date: str = None
) -> List[Dict[str, Any]]:
"""
Get journal entries from Fava (with entry hashes), optionally filtered by date.
Args:
days: If provided, only return entries from the last N days.
If None, returns all entries (default behavior).
start_date: ISO format date string (YYYY-MM-DD). If provided with end_date,
filters entries between start_date and end_date (inclusive).
end_date: ISO format date string (YYYY-MM-DD). If provided with start_date,
filters entries between start_date and end_date (inclusive).
Note:
If both days and start_date/end_date are provided, start_date/end_date takes precedence.
Returns:
List of entries (transactions, opens, closes, etc.) with entry_hash field.
@ -872,6 +884,9 @@ class FavaClient:
# Get only last 30 days
recent = await fava.get_journal_entries(days=30)
# Get entries in custom date range
custom = await fava.get_journal_entries(start_date="2024-01-01", end_date="2024-01-31")
"""
try:
async with httpx.AsyncClient(timeout=self.timeout) as client:
@ -881,9 +896,33 @@ class FavaClient:
entries = result.get("data", [])
logger.info(f"Fava /journal returned {len(entries)} entries")
# Filter by date if requested
if days is not None:
from datetime import datetime, timedelta
# Filter by date range or days
from datetime import datetime, timedelta
# Use date range if both start_date and end_date are provided
if start_date and end_date:
try:
filter_start = datetime.strptime(start_date, "%Y-%m-%d").date()
filter_end = datetime.strptime(end_date, "%Y-%m-%d").date()
filtered_entries = []
for e in entries:
entry_date_str = e.get("date")
if entry_date_str:
try:
entry_date = datetime.strptime(entry_date_str, "%Y-%m-%d").date()
if filter_start <= entry_date <= filter_end:
filtered_entries.append(e)
except (ValueError, TypeError):
# Include entries with invalid dates (shouldn't happen)
filtered_entries.append(e)
logger.info(f"Filtered to {len(filtered_entries)} entries between {start_date} and {end_date}")
entries = filtered_entries
except ValueError as e:
logger.error(f"Invalid date format: {e}")
# Return all entries if date parsing fails
# Fall back to days filter if no date range provided
elif days is not None:
cutoff_date = (datetime.now() - timedelta(days=days)).date()
filtered_entries = []
for e in entries: