fix: preserve schema 15 compatibility for v0.1.8
This commit is contained in:
@@ -99,24 +99,83 @@ def get_balance_reconciliation_report(account_id: str = "", baseline_balance: in
|
||||
effective_at = baseline_at_norm or account["last_synced_at"] or now_iso()
|
||||
valuation = None
|
||||
ambiguous_valuation = False
|
||||
valuation_status = "unavailable"
|
||||
calc = _account_balance_row(conn, account["id"], effective_at, False)
|
||||
valuation_rows = conn.execute(
|
||||
"""SELECT * FROM account_valuations v
|
||||
WHERE v.account_id=? AND v.verification_status='verified'
|
||||
AND UPPER(v.currency)=UPPER(?)
|
||||
AND v.basis_date<=?
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM account_valuations child
|
||||
WHERE child.supersedes_id=v.id
|
||||
)
|
||||
ORDER BY v.basis_date DESC, v.recorded_at DESC, v.id DESC""",
|
||||
(account["id"], account["currency"] or "KRW", effective_at[:10]),
|
||||
).fetchall()
|
||||
purposes = (
|
||||
("loan_balance", "loan", "balance")
|
||||
if account["type"] == "loan"
|
||||
else (("total_value", "balance", "cash_balance") if account["type"] == "investment" else ("cash_balance", "balance"))
|
||||
)
|
||||
transaction_rows = conn.execute(
|
||||
"""SELECT transaction_date FROM transactions
|
||||
WHERE status='active' AND account_id=? AND transaction_date<=?
|
||||
ORDER BY transaction_date ASC, transaction_datetime ASC, created_at ASC""",
|
||||
(account["id"], effective_at[:10]),
|
||||
).fetchall()
|
||||
first_transaction_date = transaction_rows[0]["transaction_date"] if transaction_rows else None
|
||||
has_opening_evidence = bool(
|
||||
first_transaction_date
|
||||
and any(
|
||||
row["basis_date"] < first_transaction_date
|
||||
and row["valuation_kind"] in purposes
|
||||
and (
|
||||
account["type"] != "loan"
|
||||
or row["representative_liability_definition"]
|
||||
in {"principal_only", "principal_interest_fees"}
|
||||
)
|
||||
for row in valuation_rows
|
||||
)
|
||||
)
|
||||
calc = _account_balance_row(conn, account["id"], effective_at, has_opening_evidence)
|
||||
for purpose in purposes:
|
||||
scoped = [
|
||||
row for row in valuation_rows
|
||||
if row["valuation_kind"] == purpose
|
||||
and (
|
||||
account["type"] != "loan"
|
||||
or row["representative_liability_definition"]
|
||||
in {"principal_only", "principal_interest_fees"}
|
||||
)
|
||||
]
|
||||
if not scoped:
|
||||
continue
|
||||
latest_basis = max(row["basis_date"] for row in scoped)
|
||||
latest = [row for row in scoped if row["basis_date"] == latest_basis]
|
||||
if len(latest) != 1:
|
||||
ambiguous_valuation = True
|
||||
else:
|
||||
valuation = latest[0]
|
||||
break
|
||||
if effective_baseline is None:
|
||||
difference = None
|
||||
ratio = None
|
||||
status = "BASELINE_REQUIRED"
|
||||
elif not calc["calculation_complete"]:
|
||||
difference = None
|
||||
ratio = None
|
||||
status = "INCOMPLETE_CALCULATION"
|
||||
elif account["type"] == "investment":
|
||||
difference = None
|
||||
ratio = None
|
||||
status = "VALUATION_UNAVAILABLE"
|
||||
else:
|
||||
difference = int(effective_baseline) - int(calc["calculated_balance"])
|
||||
ratio = abs(difference) / abs(int(effective_baseline)) if int(effective_baseline) else None
|
||||
status = "OK" if abs(difference) <= tolerance_int else "REVIEW_NEEDED"
|
||||
if account["type"] == "investment" and ambiguous_valuation:
|
||||
status = "AMBIGUOUS_VALUATION"
|
||||
difference = None
|
||||
elif account["type"] == "investment" and valuation is None:
|
||||
status = "VALUATION_UNAVAILABLE"
|
||||
difference = None
|
||||
elif not calc["calculation_complete"]:
|
||||
status = "INCOMPLETE_CALCULATION"
|
||||
difference = None
|
||||
elif account["type"] == "investment" and valuation is not None:
|
||||
status = "VALUATION_MANAGED"
|
||||
difference = None
|
||||
items.append({
|
||||
"account_id": account["id"],
|
||||
"account_name": account["name"],
|
||||
|
||||
Reference in New Issue
Block a user