feat: deliver schema 15 monthly settlement lifecycle
This commit is contained in:
@@ -3,23 +3,18 @@ from .shared import Any, VALID_ACCOUNT_TYPES, db, fail, new_id, normalize_date,
|
||||
|
||||
|
||||
def _record_balance_candidate(conn: Any, account: dict[str, Any], balance: Any = None, basis_date: str | None = None) -> None:
|
||||
balance = account.get("last_balance") if balance is None else balance
|
||||
basis_date = account.get("last_balance_basis_date") if basis_date is None else basis_date
|
||||
if balance is None or not str(basis_date or ""):
|
||||
return
|
||||
try:
|
||||
from .account_valuation_service import record_account_valuation_candidate
|
||||
record_account_valuation_candidate(conn, account["id"], str(basis_date), int(balance), account.get("currency", "KRW"), "account_write", account.get("updated_at", ""), f"account-balance:{account['id']}:{str(basis_date)}:{balance}", "account balance write candidate")
|
||||
except (ValueError, TypeError):
|
||||
return
|
||||
"""Deprecated: balances remain on accounts; no valuation row is created."""
|
||||
return
|
||||
|
||||
|
||||
def create_ledger_account(name: str, type: str = "bank", institution: str = "", currency: str = "KRW", active: bool = True, memo: str = "", account_number_masked: str = "", holder_name: str = "", last_balance: int | None = None, last_synced_at: str = "", statement_status: str = "unknown", liquidity_bucket: str = "other", db_path: str | None = None, last_balance_basis_date: str = "") -> dict[str, Any]:
|
||||
def create_ledger_account(name: str, type: str = "bank", institution: str = "", currency: str = "KRW", active: bool = True, memo: str = "", account_number_masked: str = "", holder_name: str = "", last_balance: int | None = None, last_synced_at: str = "", statement_status: str = "unknown", liquidity_bucket: str | None = None, db_path: str | None = None, last_balance_basis_date: str = "") -> dict[str, Any]:
|
||||
if not name.strip(): return fail("validation_error", "account name is required")
|
||||
if type not in VALID_ACCOUNT_TYPES: return fail("validation_error", f"type must be one of {sorted(VALID_ACCOUNT_TYPES)}")
|
||||
try:
|
||||
statement_status_norm = normalize_statement_status(statement_status)
|
||||
liquidity_bucket_norm = normalize_liquidity_bucket(liquidity_bucket)
|
||||
liquidity_bucket_norm = normalize_liquidity_bucket(
|
||||
"real_estate" if liquidity_bucket is None and type == "real_estate" else liquidity_bucket
|
||||
)
|
||||
except Exception as e: return fail("validation_error", str(e))
|
||||
ts = now_iso(); account_id = new_id("acct")
|
||||
try:
|
||||
@@ -79,14 +74,7 @@ def update_ledger_account(account_id: str, db_path: str | None = None, **fields:
|
||||
if not updates: return fail("validation_error", "no fields to update")
|
||||
target_type = fields.get("type", current["type"])
|
||||
if str(current["type"]).lower() != "loan" and target_type == "loan":
|
||||
invalid_valuation = conn.execute(
|
||||
"SELECT 1 FROM account_valuations "
|
||||
"WHERE account_id=? AND (representative_liability_definition IS NULL "
|
||||
"OR representative_liability_definition NOT IN (?, ?)) LIMIT 1",
|
||||
(account_id, "principal_only", "principal_interest_fees"),
|
||||
).fetchone()
|
||||
if invalid_valuation is not None:
|
||||
return fail("validation_error", "loan account requires a valid representative liability definition for every valuation")
|
||||
return fail("unsupported", "account valuation history is unavailable; loan conversion requires a supported liability valuation source")
|
||||
stored_date = str(current["last_balance_basis_date"] or "")[:10]
|
||||
incoming_date = normalized_basis if basis_update else ""
|
||||
historical = bool(balance_update and incoming_date and stored_date and incoming_date < stored_date)
|
||||
|
||||
Reference in New Issue
Block a user