mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-13 09:02:23 +00:00
Add hide_missing_ids filter to transaction queries
- Add hide_missing_ids parameter to database functions to filter out transactions without internalTransactionId - Update API routes to support the new filter parameter - Update unit tests to include the new parameter - Add opencode.json configuration file
This commit is contained in:
committed by
Elisiário Couto
parent
c5fd26cb3e
commit
947342e196
@@ -210,6 +210,7 @@ def get_transactions(
|
|||||||
min_amount=None,
|
min_amount=None,
|
||||||
max_amount=None,
|
max_amount=None,
|
||||||
search=None,
|
search=None,
|
||||||
|
hide_missing_ids=True,
|
||||||
):
|
):
|
||||||
"""Get transactions from SQLite database with optional filtering"""
|
"""Get transactions from SQLite database with optional filtering"""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -249,6 +250,11 @@ def get_transactions(
|
|||||||
query += " AND description LIKE ?"
|
query += " AND description LIKE ?"
|
||||||
params.append(f"%{search}%")
|
params.append(f"%{search}%")
|
||||||
|
|
||||||
|
if hide_missing_ids:
|
||||||
|
query += (
|
||||||
|
" AND internalTransactionId IS NOT NULL AND internalTransactionId != ''"
|
||||||
|
)
|
||||||
|
|
||||||
# Add ordering and pagination
|
# Add ordering and pagination
|
||||||
query += " ORDER BY transactionDate DESC"
|
query += " ORDER BY transactionDate DESC"
|
||||||
|
|
||||||
@@ -397,6 +403,11 @@ def get_transaction_count(account_id=None, **filters):
|
|||||||
query += " AND description LIKE ?"
|
query += " AND description LIKE ?"
|
||||||
params.append(f"%{filters['search']}%")
|
params.append(f"%{filters['search']}%")
|
||||||
|
|
||||||
|
if filters.get("hide_missing_ids", True):
|
||||||
|
query += (
|
||||||
|
" AND internalTransactionId IS NOT NULL AND internalTransactionId != ''"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute(query, params)
|
cursor.execute(query, params)
|
||||||
count = cursor.fetchone()[0]
|
count = cursor.fetchone()[0]
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ async def get_all_transactions(
|
|||||||
summary_only: bool = Query(
|
summary_only: bool = Query(
|
||||||
default=True, description="Return transaction summaries only"
|
default=True, description="Return transaction summaries only"
|
||||||
),
|
),
|
||||||
|
hide_missing_ids: bool = Query(
|
||||||
|
default=True, description="Hide transactions without internalTransactionId"
|
||||||
|
),
|
||||||
date_from: Optional[str] = Query(
|
date_from: Optional[str] = Query(
|
||||||
default=None, description="Filter from date (YYYY-MM-DD)"
|
default=None, description="Filter from date (YYYY-MM-DD)"
|
||||||
),
|
),
|
||||||
@@ -47,6 +50,18 @@ async def get_all_transactions(
|
|||||||
min_amount=min_amount,
|
min_amount=min_amount,
|
||||||
max_amount=max_amount,
|
max_amount=max_amount,
|
||||||
search=search,
|
search=search,
|
||||||
|
hide_missing_ids=hide_missing_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get total count for pagination info (respecting the same filters)
|
||||||
|
total_transactions = await database_service.get_transaction_count_from_db(
|
||||||
|
account_id=account_id,
|
||||||
|
date_from=date_from,
|
||||||
|
date_to=date_to,
|
||||||
|
min_amount=min_amount,
|
||||||
|
max_amount=max_amount,
|
||||||
|
search=search,
|
||||||
|
hide_missing_ids=hide_missing_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get total count for pagination info
|
# Get total count for pagination info
|
||||||
@@ -111,6 +126,9 @@ async def get_all_transactions(
|
|||||||
async def get_transaction_stats(
|
async def get_transaction_stats(
|
||||||
days: int = Query(default=30, description="Number of days to include in stats"),
|
days: int = Query(default=30, description="Number of days to include in stats"),
|
||||||
account_id: Optional[str] = Query(default=None, description="Filter by account ID"),
|
account_id: Optional[str] = Query(default=None, description="Filter by account ID"),
|
||||||
|
hide_missing_ids: bool = Query(
|
||||||
|
default=True, description="Hide transactions without internalTransactionId"
|
||||||
|
),
|
||||||
) -> APIResponse:
|
) -> APIResponse:
|
||||||
"""Get transaction statistics for the last N days from database"""
|
"""Get transaction statistics for the last N days from database"""
|
||||||
try:
|
try:
|
||||||
@@ -128,6 +146,7 @@ async def get_transaction_stats(
|
|||||||
date_from=date_from,
|
date_from=date_from,
|
||||||
date_to=date_to,
|
date_to=date_to,
|
||||||
limit=None, # Get all matching transactions for stats
|
limit=None, # Get all matching transactions for stats
|
||||||
|
hide_missing_ids=hide_missing_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Calculate stats
|
# Calculate stats
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class DatabaseService:
|
|||||||
min_amount: Optional[float] = None,
|
min_amount: Optional[float] = None,
|
||||||
max_amount: Optional[float] = None,
|
max_amount: Optional[float] = None,
|
||||||
search: Optional[str] = None,
|
search: Optional[str] = None,
|
||||||
|
hide_missing_ids: bool = True,
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
"""Get transactions from SQLite database"""
|
"""Get transactions from SQLite database"""
|
||||||
if not self.sqlite_enabled:
|
if not self.sqlite_enabled:
|
||||||
@@ -131,6 +132,7 @@ class DatabaseService:
|
|||||||
min_amount=min_amount,
|
min_amount=min_amount,
|
||||||
max_amount=max_amount,
|
max_amount=max_amount,
|
||||||
search=search,
|
search=search,
|
||||||
|
hide_missing_ids=hide_missing_ids,
|
||||||
)
|
)
|
||||||
logger.debug(f"Retrieved {len(transactions)} transactions from database")
|
logger.debug(f"Retrieved {len(transactions)} transactions from database")
|
||||||
return transactions
|
return transactions
|
||||||
@@ -146,6 +148,7 @@ class DatabaseService:
|
|||||||
min_amount: Optional[float] = None,
|
min_amount: Optional[float] = None,
|
||||||
max_amount: Optional[float] = None,
|
max_amount: Optional[float] = None,
|
||||||
search: Optional[str] = None,
|
search: Optional[str] = None,
|
||||||
|
hide_missing_ids: bool = True,
|
||||||
) -> int:
|
) -> int:
|
||||||
"""Get total count of transactions from SQLite database"""
|
"""Get total count of transactions from SQLite database"""
|
||||||
if not self.sqlite_enabled:
|
if not self.sqlite_enabled:
|
||||||
@@ -162,7 +165,9 @@ class DatabaseService:
|
|||||||
# Remove None values
|
# Remove None values
|
||||||
filters = {k: v for k, v in filters.items() if v is not None}
|
filters = {k: v for k, v in filters.items() if v is not None}
|
||||||
|
|
||||||
count = sqlite_db.get_transaction_count(account_id=account_id, **filters)
|
count = sqlite_db.get_transaction_count(
|
||||||
|
account_id=account_id, hide_missing_ids=hide_missing_ids, **filters
|
||||||
|
)
|
||||||
logger.debug(f"Total transaction count: {count}")
|
logger.debug(f"Total transaction count: {count}")
|
||||||
return count
|
return count
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
7
opencode.json
Normal file
7
opencode.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json",
|
||||||
|
"permission": {
|
||||||
|
"edit": "ask",
|
||||||
|
"bash": "ask"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -166,6 +166,7 @@ class TestTransactionsAPI:
|
|||||||
min_amount=-50.0,
|
min_amount=-50.0,
|
||||||
max_amount=0.0,
|
max_amount=0.0,
|
||||||
search="Coffee",
|
search="Coffee",
|
||||||
|
hide_missing_ids=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_transactions_empty_result(
|
def test_get_transactions_empty_result(
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ class TestDatabaseService:
|
|||||||
min_amount=None,
|
min_amount=None,
|
||||||
max_amount=None,
|
max_amount=None,
|
||||||
search=None,
|
search=None,
|
||||||
|
hide_missing_ids=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def test_get_transactions_from_db_with_filters(
|
async def test_get_transactions_from_db_with_filters(
|
||||||
@@ -129,6 +130,7 @@ class TestDatabaseService:
|
|||||||
min_amount=-50.0,
|
min_amount=-50.0,
|
||||||
max_amount=0.0,
|
max_amount=0.0,
|
||||||
search="Coffee",
|
search="Coffee",
|
||||||
|
hide_missing_ids=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def test_get_transactions_from_db_sqlite_disabled(self, database_service):
|
async def test_get_transactions_from_db_sqlite_disabled(self, database_service):
|
||||||
@@ -158,7 +160,9 @@ class TestDatabaseService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert result == 42
|
assert result == 42
|
||||||
mock_get_count.assert_called_once_with(account_id="test-account-123")
|
mock_get_count.assert_called_once_with(
|
||||||
|
account_id="test-account-123", hide_missing_ids=True
|
||||||
|
)
|
||||||
|
|
||||||
async def test_get_transaction_count_from_db_with_filters(self, database_service):
|
async def test_get_transaction_count_from_db_with_filters(self, database_service):
|
||||||
"""Test getting transaction count with filters."""
|
"""Test getting transaction count with filters."""
|
||||||
@@ -178,6 +182,7 @@ class TestDatabaseService:
|
|||||||
date_from="2025-09-01",
|
date_from="2025-09-01",
|
||||||
min_amount=-100.0,
|
min_amount=-100.0,
|
||||||
search="Coffee",
|
search="Coffee",
|
||||||
|
hide_missing_ids=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def test_get_transaction_count_from_db_sqlite_disabled(
|
async def test_get_transaction_count_from_db_sqlite_disabled(
|
||||||
|
|||||||
Reference in New Issue
Block a user