fix: preserve schema 15 compatibility for v0.1.8
This commit is contained in:
@@ -33,7 +33,7 @@ def _review_cashflow(month: str, db_path: str | None = None, conn=None) -> dict[
|
||||
start, end = _month_range(month)
|
||||
rows = conn.execute(f"SELECT {CASHFLOW_KIND_SQL} AS cashflow_kind, t.category, t.subcategory, t.currency, SUM(t.amount) AS amount, COUNT(*) AS count FROM transactions t LEFT JOIN ledger_categories lc ON lc.active=1 AND t.category=lc.category AND t.subcategory=lc.subcategory WHERE t.status='active' AND t.transaction_date>=? AND t.transaction_date<? GROUP BY {CASHFLOW_KIND_SQL}, t.category, t.subcategory, t.currency ORDER BY cashflow_kind, amount DESC", (start, end)).fetchall()
|
||||
categories = [dict(r) for r in rows]
|
||||
source_rows = conn.execute(f"SELECT t.id, t.transaction_date, t.type, t.amount, t.currency, t.category, t.subcategory, t.account_id FROM transactions t LEFT JOIN ledger_categories lc ON lc.active=1 AND t.category=lc.category AND t.subcategory=lc.subcategory WHERE t.status='active' AND t.transaction_date>=? AND t.transaction_date<? ORDER BY t.id", (start, end)).fetchall()
|
||||
source_rows = conn.execute("SELECT t.id, t.transaction_date, t.type, t.amount, t.currency, t.category, t.subcategory, t.account_id FROM transactions t LEFT JOIN ledger_categories lc ON lc.active=1 AND t.category=lc.category AND t.subcategory=lc.subcategory WHERE t.status='active' AND t.transaction_date>=? AND t.transaction_date<? ORDER BY t.id", (start, end)).fetchall()
|
||||
totals = {}
|
||||
for item in categories: totals[item['cashflow_kind']] = totals.get(item['cashflow_kind'], 0) + int(item['amount'] or 0)
|
||||
income, expenses = totals.get('income', 0), totals.get('expense', 0)
|
||||
@@ -396,7 +396,6 @@ def unlink_account_snapshot(snapshot_id: str, monthly_settlement_id: str, db_pat
|
||||
return fail("db_error", "account snapshot unlink failed")
|
||||
|
||||
def list_monthly_settlement_history(month: str = "", db_path: str | None = None) -> dict[str, Any]:
|
||||
return fail("unsupported", "run history unavailable")
|
||||
"""Return immutable close/correction records; lifecycle history is authoritative."""
|
||||
try:
|
||||
selected = normalize_month(month) if month else ""
|
||||
@@ -419,7 +418,6 @@ def list_monthly_settlement_history(month: str = "", db_path: str | None = None)
|
||||
|
||||
|
||||
def get_monthly_settlement_history_record(run_id: str, db_path: str | None = None) -> dict[str, Any]:
|
||||
return fail("unsupported", "run history unavailable")
|
||||
"""Read one immutable close/correction record by run ID."""
|
||||
if not isinstance(run_id, str) or not run_id:
|
||||
return fail("validation_error", "run_id is required")
|
||||
@@ -563,7 +561,6 @@ def get_monthly_settlement_summary(month: str = "", db_path: str | None = None)
|
||||
|
||||
|
||||
def get_monthly_settlement_snapshot(month: str = "", run_id: str = "", db_path: str | None = None) -> dict[str, Any]:
|
||||
return fail("unsupported", "run history unavailable")
|
||||
"""Read a persisted monthly settlement close without consulting live ledger state."""
|
||||
if not isinstance(month, str) or not isinstance(run_id, str):
|
||||
return fail("validation_error", "month and run_id must be strings")
|
||||
@@ -582,32 +579,38 @@ def get_monthly_settlement_snapshot(month: str = "", run_id: str = "", db_path:
|
||||
try:
|
||||
with read_db(db_path) as conn:
|
||||
tables = {r["name"] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'")}
|
||||
if "asset_snapshot_runs" not in tables or "account_snapshot" not in tables:
|
||||
if "asset_snapshot_runs" not in tables or "asset_snapshots" not in tables:
|
||||
return fail("not_found", "settlement snapshot not found")
|
||||
run = None
|
||||
rows = []
|
||||
legacy = False
|
||||
metadata: dict[str, Any] = {}
|
||||
run_cols = {r["name"] for r in conn.execute("PRAGMA table_info(asset_snapshot_runs)")}
|
||||
if run_id:
|
||||
# Pre-comprehensive headers are intentionally read without
|
||||
# assuming schema-16-only columns.
|
||||
run = conn.execute("SELECT rowid AS _run_rowid,* FROM asset_snapshot_runs WHERE id=?", (run_id,)).fetchone()
|
||||
if run:
|
||||
from .assets_service import _snapshot_rows_for_run
|
||||
rows, metadata = _snapshot_rows_for_run(conn, run_id)
|
||||
else:
|
||||
cols = {r["name"] for r in conn.execute("PRAGMA table_info(account_snapshot)")}
|
||||
cols = {r["name"] for r in conn.execute("PRAGMA table_info(asset_snapshots)")}
|
||||
if {"snapshot_run_id", "closed_at"} <= cols:
|
||||
rows = conn.execute("SELECT rowid AS _rowid,* FROM account_snapshot WHERE snapshot_run_id=? AND closed_at<>'' ORDER BY rowid", (run_id,)).fetchall()
|
||||
rows = conn.execute("SELECT rowid AS _rowid,* FROM asset_snapshots WHERE snapshot_run_id=? AND closed_at<>'' ORDER BY rowid", (run_id,)).fetchall()
|
||||
if rows:
|
||||
legacy = True
|
||||
metadata = {"snapshot_run_id": run_id, "legacy_closed": True, "close_status": "legacy_read_only"}
|
||||
else:
|
||||
if selected_month and "settlement_month" in run_cols:
|
||||
run = conn.execute("SELECT rowid AS _run_rowid,* FROM asset_snapshot_runs WHERE basis_date=? ORDER BY rowid DESC LIMIT 1", (_month_end_date(selected_month),)).fetchone()
|
||||
elif selected_month:
|
||||
run = conn.execute("SELECT rowid AS _run_rowid,* FROM asset_snapshot_runs WHERE basis_date=? ORDER BY rowid DESC LIMIT 1", (_month_end_date(selected_month),)).fetchone()
|
||||
if selected_month:
|
||||
run_columns = {r["name"] for r in conn.execute("PRAGMA table_info(asset_snapshot_runs)")}
|
||||
comprehensive_columns = {"snapshot_schema_version", "aggregation_version"}
|
||||
if comprehensive_columns <= run_columns:
|
||||
run = conn.execute(
|
||||
"""SELECT rowid AS _run_rowid,* FROM asset_snapshot_runs
|
||||
WHERE basis_date=? AND snapshot_schema_version=1
|
||||
AND aggregation_version='comprehensive-v1'
|
||||
ORDER BY rowid DESC LIMIT 1""",
|
||||
(_month_end_date(selected_month),),
|
||||
).fetchone()
|
||||
if run is None:
|
||||
run = conn.execute("SELECT rowid AS _run_rowid,* FROM asset_snapshot_runs WHERE basis_date=? ORDER BY rowid DESC LIMIT 1", (_month_end_date(selected_month),)).fetchone()
|
||||
if run is None:
|
||||
basis = _month_end_date(selected_month) if selected_month else ""
|
||||
if basis:
|
||||
@@ -650,7 +653,7 @@ def get_monthly_settlement_snapshot(month: str = "", run_id: str = "", db_path:
|
||||
legacy = not comprehensive
|
||||
cashflows = []
|
||||
if comprehensive and "settlement_cashflow_snapshots" in tables:
|
||||
cashflows = [dict(r) for r in conn.execute("SELECT cashflow_kind,category,subcategory,amount,transaction_count,currency FROM settlement_cashflow_snapshots WHERE monthly_settlement_id=? ORDER BY cashflow_kind,category,subcategory,currency", (rid,))]
|
||||
cashflows = [dict(r) for r in conn.execute("SELECT cashflow_kind,category,subcategory,amount,transaction_count,currency FROM settlement_cashflow_snapshots WHERE settlement_run_id=? ORDER BY cashflow_kind,category,subcategory,currency", (rid,))]
|
||||
totals = {"income_total": field("income_total") if comprehensive else None, "expense_total": field("expense_total") if comprehensive else None, "net_cashflow": field("net_cashflow") if comprehensive else None, "total_assets": field("total_assets") if comprehensive else None, "total_liabilities": field("total_liabilities") if comprehensive else None, "net_worth": field("net_worth") if comprehensive else None}
|
||||
safe_items = []
|
||||
for row in rows:
|
||||
|
||||
Reference in New Issue
Block a user