mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
add "debit_card" as a new AccountType (#16)
This commit is contained in:
@@ -4,6 +4,7 @@ import enum
|
||||
|
||||
class AccountType(str, enum.Enum):
|
||||
CHECKING = "checking"
|
||||
DEBIT_CARD = "debit_card"
|
||||
SAVINGS = "savings"
|
||||
CREDIT_CARD = "credit_card"
|
||||
CASH = "cash"
|
||||
|
||||
@@ -33,7 +33,7 @@ MAX_LOOKBACK_MONTHS = 24
|
||||
# Accounts where a big, untouched balance means money isn't working — a
|
||||
# credit card balance isn't "your cash", an investment account is already
|
||||
# invested, and OTHER is too ambiguous to guess at.
|
||||
_IDLE_CASH_ACCOUNT_TYPES = (AccountType.CHECKING, AccountType.SAVINGS, AccountType.CASH)
|
||||
_IDLE_CASH_ACCOUNT_TYPES = (AccountType.CHECKING, AccountType.DEBIT_CARD, AccountType.SAVINGS, AccountType.CASH)
|
||||
|
||||
|
||||
def _previous_month(year: int, month: int) -> tuple[int, int]:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
asset class.
|
||||
|
||||
Design note: "Cash" is not stored anywhere — it's derived live from
|
||||
Account/Transaction data (checking/savings/cash/investment accounts) so the
|
||||
Account/Transaction data (checking/debit-card/savings/cash/investment accounts) so the
|
||||
Transactions feature stays the single source of truth for liquid money.
|
||||
Investment accounts count here too: their balance is uninvested/unallocated
|
||||
money sitting on the account, not the market value of what's actually
|
||||
@@ -36,7 +36,13 @@ from app.schemas.net_worth import (
|
||||
RiskLevelSummary,
|
||||
)
|
||||
|
||||
CASH_ACCOUNT_TYPES = {AccountType.CHECKING, AccountType.SAVINGS, AccountType.CASH, AccountType.INVESTMENT}
|
||||
CASH_ACCOUNT_TYPES = {
|
||||
AccountType.CHECKING,
|
||||
AccountType.DEBIT_CARD,
|
||||
AccountType.SAVINGS,
|
||||
AccountType.CASH,
|
||||
AccountType.INVESTMENT,
|
||||
}
|
||||
|
||||
RANGE_DAYS = {"30d": 30, "90d": 90, "1y": 365, "5y": 365 * 5}
|
||||
|
||||
|
||||
34
backend/tests/test_accounts.py
Normal file
34
backend/tests/test_accounts.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""Account-type behavior shared by the accounts API and financial summaries."""
|
||||
from datetime import date
|
||||
|
||||
from httpx import AsyncClient
|
||||
|
||||
from tests.helpers import money, txn_payload
|
||||
|
||||
|
||||
async def test_debit_card_is_a_liquid_account_type(client: AsyncClient, categories):
|
||||
response = await client.post(
|
||||
"/accounts",
|
||||
json={"name": "Debit card", "type": "debit_card", "currency": "RUB"},
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
debit_card = response.json()
|
||||
assert debit_card["type"] == "debit_card"
|
||||
|
||||
transaction = await client.post(
|
||||
"/transactions",
|
||||
json=txn_payload(
|
||||
debit_card["id"],
|
||||
type="income",
|
||||
amount="1000.00",
|
||||
category_id=categories["Salary"]["id"],
|
||||
date=date.today().isoformat(),
|
||||
),
|
||||
)
|
||||
assert transaction.status_code == 201
|
||||
|
||||
summary = await client.get("/net-worth/summary", params={"range": "all"})
|
||||
|
||||
assert summary.status_code == 200
|
||||
assert money(summary.json()["current"]) == money("1000.00")
|
||||
@@ -51,6 +51,25 @@ async def test_idle_cash_ignores_investment_accounts(client: AsyncClient, catego
|
||||
assert "idle_cash" not in await _alert_keys(client)
|
||||
|
||||
|
||||
async def test_idle_cash_includes_debit_cards(client: AsyncClient, categories):
|
||||
debit_card = await client.post(
|
||||
"/accounts", json={"name": "Debit card", "type": "debit_card", "currency": "USD"}
|
||||
)
|
||||
debit_card_id = debit_card.json()["id"]
|
||||
await client.post(
|
||||
"/transactions",
|
||||
json=_txn(
|
||||
debit_card_id,
|
||||
type="income",
|
||||
amount="5000.00",
|
||||
category_id=categories["Salary"]["id"],
|
||||
date=STALE_DATE,
|
||||
),
|
||||
)
|
||||
|
||||
assert "idle_cash" in await _alert_keys(client)
|
||||
|
||||
|
||||
async def test_idle_cash_respects_custom_threshold(client: AsyncClient, account_id, categories):
|
||||
await client.post(
|
||||
"/transactions",
|
||||
|
||||
Reference in New Issue
Block a user