# backend/app/modules/trial_balance/service.py from decimal import Decimal from typing import Dict, Any, List from app.core.database import get_connection def D(x) -> Decimal: return Decimal(str(x or 0)) def fetch_trial_balance(date_from: str, date_to: str): with get_connection() as conn, conn.cursor() as cur: cur.execute(""" SELECT account_id, account_code, account_name, account_type FROM accounts WHERE is_active = true ORDER BY account_code """) accounts = cur.fetchall() result_accounts: List[Dict[str, Any]] = [] total_opening = Decimal("0") total_debit = Decimal("0") total_credit = Decimal("0") total_closing = Decimal("0") for acc in accounts: aid = acc["account_id"] # 期首 cur.execute(""" SELECT COALESCE(SUM(l.debit - l.credit), 0) AS opening FROM journal_lines l JOIN journal_entries j ON j.journal_id = l.journal_id WHERE l.account_id = %s AND j.journal_date < %s """, (aid, date_from)) opening = D(cur.fetchone()["opening"]) # 当期 cur.execute(""" SELECT COALESCE(SUM(l.debit), 0) AS debit, COALESCE(SUM(l.credit), 0) AS credit FROM journal_lines l JOIN journal_entries j ON j.journal_id = l.journal_id WHERE l.account_id = %s AND j.journal_date BETWEEN %s AND %s """, (aid, date_from, date_to)) row = cur.fetchone() debit = D(row["debit"]) credit = D(row["credit"]) closing = opening + debit - credit total_opening += opening total_debit += debit total_credit += credit total_closing += closing result_accounts.append({ "account_id": aid, "account_code": acc["account_code"], "account_name": acc["account_name"], "account_type": acc["account_type"], "opening_balance": str(opening), "debit": str(debit), "credit": str(credit), "closing_balance": str(closing), }) return { "totals": { "opening_balance": str(total_opening), "debit": str(total_debit), "credit": str(total_credit), "closing_balance": str(total_closing) }, "accounts": result_accounts }