Coverage for dibbler / queries / current_interest.py: 65%
22 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-12 13:57 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-12 13:57 +0000
1from datetime import datetime
3from sqlalchemy import BindParameter, bindparam, select
4from sqlalchemy.orm import Session
6from dibbler.models import Transaction, TransactionType
7from dibbler.models.Transaction import DEFAULT_INTEREST_RATE_PERCENT
8from dibbler.queries.query_helpers import until_filter
11def current_interest(
12 sql_session: Session,
13 until_time: BindParameter[datetime] | datetime | None = None,
14 until_transaction: BindParameter[Transaction] | Transaction | None = None,
15 until_inclusive: bool = True,
16) -> int:
17 """
18 Get the current interest rate percentage as of a given time or transaction.
20 Returns the interest rate percentage as an integer.
21 """
23 if not (until_time is None or until_transaction is None): 23 ↛ 24line 23 didn't jump to line 24 because the condition on line 23 was never true
24 raise ValueError("Cannot filter by both until_time and until_transaction.")
26 if isinstance(until_time, datetime): 26 ↛ 27line 26 didn't jump to line 27 because the condition on line 26 was never true
27 until_time = BindParameter("until_time", value=until_time)
29 if isinstance(until_transaction, Transaction): 29 ↛ 30line 29 didn't jump to line 30 because the condition on line 29 was never true
30 if until_transaction.id is None:
31 raise ValueError("until_transaction must be persisted in the database.")
32 until_transaction_id = bindparam("until_transaction_id", value=until_transaction.id)
33 else:
34 until_transaction_id = None
36 result = sql_session.scalars(
37 select(Transaction)
38 .where(
39 Transaction.type_ == TransactionType.ADJUST_INTEREST,
40 until_filter(
41 until_time=until_time,
42 until_transaction_id=until_transaction_id,
43 until_inclusive=until_inclusive,
44 ),
45 )
46 .order_by(Transaction.time.desc())
47 .limit(1)
48 ).one_or_none()
50 if result is None:
51 return DEFAULT_INTEREST_RATE_PERCENT
52 elif result.interest_rate_percent is None: 52 ↛ 53line 52 didn't jump to line 53 because the condition on line 52 was never true
53 return DEFAULT_INTEREST_RATE_PERCENT
54 else:
55 return result.interest_rate_percent