diff --git a/backend/app/modules/opening_balances/lock_router.py b/backend/app/modules/opening_balances/lock_router.py index 527c2ed..33e6cf7 100644 --- a/backend/app/modules/opening_balances/lock_router.py +++ b/backend/app/modules/opening_balances/lock_router.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel from app.core.database import get_connection @@ -10,6 +10,25 @@ router = APIRouter( class LockRequest(BaseModel): fiscal_year: int +@router.get("/lock-status", summary="期首残高確定状態確認") +def get_lock_status(fiscal_year: int = Query(..., description="会計年度")): + try: + with get_connection() as conn, conn.cursor() as cur: + cur.execute(""" + SELECT is_locked + FROM fiscal_year_locks + WHERE fiscal_year = %s + """, (fiscal_year,)) + row = cur.fetchone() + + if row: + return {"is_locked": row[0]} + else: + return {"is_locked": False} + except Exception: + # テーブルが存在しない場合は未ロック扱い + return {"is_locked": False} + @router.post("/lock", summary="期首残高年度確定") def lock_fiscal_year(req: LockRequest): diff --git a/backend/app/modules/trial_balance/service.py b/backend/app/modules/trial_balance/service.py index 5a3a54b..83bd5e7 100644 --- a/backend/app/modules/trial_balance/service.py +++ b/backend/app/modules/trial_balance/service.py @@ -6,10 +6,33 @@ from app.core.database import get_connection def D(x) -> Decimal: return Decimal(str(x or 0)) +# 科目グループ定義(表示順序を制御)- PDFフォーマットに準拠 +ACCOUNT_GROUPS = [ + # 資産の部 + ("現金・預金合計", ["101", "102", "103", "104"]), + ("流動資産合計", ["101", "102", "103", "104", "201", "202", "203", "204", "205"]), + ("有価証券合計", ["301"]), + ("有形固定資産合計", ["401", "402", "403", "404", "405", "406", "407"]), + ("無形固定資産合計", ["408"]), + ("投資その他の資産合計", ["301", "410"]), + ("固定資産合計", ["301", "401", "402", "403", "404", "405", "406", "407", "408", "410"]), + ("資産合計", ["101", "102", "103", "104", "201", "202", "203", "204", "205", "301", "401", "402", "403", "404", "405", "406", "407", "408", "410"]), + # 負債の部 + ("仕入債務合計", ["501"]), + ("流動負債合計", ["501", "502", "503", "504", "505", "506", "507", "508"]), + ("固定負債合計", ["509"]), + ("負債合計", ["501", "502", "503", "504", "505", "506", "507", "508", "509"]), + # 資本の部 + ("資本金合計", ["601"]), + ("利益剰余金合計", ["602"]), + ("純資産合計", ["601", "602"]) +] + 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 @@ -18,37 +41,50 @@ def fetch_trial_balance(date_from: str, date_to: str): """) 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") + # 科目データを格納 + account_data: Dict[str, Dict[str, Any]] = {} for acc in accounts: aid = acc["account_id"] + code = acc["account_code"] - # 期首 + # 期首残高: opening_balances テーブルの残高 + date_from より前の仕訳 + # まず opening_balances テーブルから取得 + cur.execute(""" + SELECT COALESCE(opening_debit, 0) - COALESCE(opening_credit, 0) AS ob + FROM opening_balances + WHERE account_id = %s + AND fiscal_year = EXTRACT(YEAR FROM %s::date) + """, (aid, date_from)) + ob_row = cur.fetchone() + opening_balance_from_table = D(ob_row["ob"]) if ob_row else D(0) + + # date_from より前の仕訳による増減 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 - AND j.is_deleted = false + JOIN journal_entries j + ON j.journal_entry_id = l.journal_entry_id WHERE l.account_id = %s - AND j.journal_date < %s + AND j.entry_date < %s + AND j.is_deleted = false """, (aid, date_from)) - opening = D(cur.fetchone()["opening"]) + opening_from_journals = D(cur.fetchone()["opening"]) + + # 合計 + opening = opening_balance_from_table + opening_from_journals - # 当期 + # 当期増減(date_from ~ date_to) cur.execute(""" SELECT - COALESCE(SUM(l.debit), 0) AS debit, + 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 - AND j.is_deleted = false + JOIN journal_entries j + ON j.journal_entry_id = l.journal_entry_id WHERE l.account_id = %s - AND j.journal_date BETWEEN %s AND %s + AND j.entry_date BETWEEN %s AND %s + AND j.is_deleted = false """, (aid, date_from, date_to)) row = cur.fetchone() debit = D(row["debit"]) @@ -56,28 +92,107 @@ def fetch_trial_balance(date_from: str, date_to: str): closing = opening + debit - credit - total_opening += opening - total_debit += debit - total_credit += credit - total_closing += closing - - result_accounts.append({ + account_data[code] = { "account_id": aid, - "account_code": acc["account_code"], + "account_code": 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), + "opening_balance": opening, + "debit": debit, + "credit": credit, + "closing_balance": closing, + } + + # 結果リスト(グループ化) + result_accounts: List[Dict[str, Any]] = [] + + # 既に挿入された合計行を追跡 + inserted_totals = set() + + # 大区分の合計を保存(資産・負債・純資産の総合計) + grand_total_closing = D(0) + + # 個別科目を追加 + for code in sorted(account_data.keys()): + data = account_data[code] + result_accounts.append({ + "account_code": data["account_code"], + "account_name": data["account_name"], + "account_type": data["account_type"], + "opening_balance": str(data["opening_balance"]), + "debit": str(data["debit"]), + "credit": str(data["credit"]), + "closing_balance": str(data["closing_balance"]), + "ratio": None, # 後で計算 + "is_total": False }) + + # 大区分合計用に総計を積算 + grand_total_closing += data["closing_balance"] + + # 合計行を挿入(グループ定義の順序で) + for group_name, group_codes in ACCOUNT_GROUPS: + # このグループにまだ合計行を挿入していない + if group_name in inserted_totals: + continue + + # 現在の科目がこのグループに含まれる + if code not in group_codes: + continue + + # このグループの全科目を取得 + group_codes_in_data = [gc for gc in group_codes if gc in account_data] + if not group_codes_in_data: + continue + + # グループの最後の科目コードを取得 + last_code_in_group = max(group_codes_in_data) + + # 現在の科目がグループの最後の科目の場合 + if code == last_code_in_group: + # グループ合計を計算 + group_opening = sum(account_data[gc]["opening_balance"] for gc in group_codes_in_data) + group_debit = sum(account_data[gc]["debit"] for gc in group_codes_in_data) + group_credit = sum(account_data[gc]["credit"] for gc in group_codes_in_data) + group_closing = sum(account_data[gc]["closing_balance"] for gc in group_codes_in_data) + + result_accounts.append({ + "account_code": "", + "account_name": group_name, + "account_type": "", + "opening_balance": str(group_opening), + "debit": str(group_debit), + "credit": str(group_credit), + "closing_balance": str(group_closing), + "ratio": None, # 後で計算 + "is_total": True + }) + + inserted_totals.add(group_name) + + # 構成比を計算(総資産に対する割合) + for acc in result_accounts: + closing = D(acc["closing_balance"]) + if grand_total_closing != 0: + ratio = (closing / grand_total_closing) * 100 + acc["ratio"] = f"{ratio:.2f}" + else: + acc["ratio"] = "0.00" + + # 総合計を計算 + total_opening = sum(data["opening_balance"] for data in account_data.values()) + total_debit = sum(data["debit"] for data in account_data.values()) + total_credit = sum(data["credit"] for data in account_data.values()) + total_closing = sum(data["closing_balance"] for data in account_data.values()) return { "totals": { "opening_balance": str(total_opening), "debit": str(total_debit), "credit": str(total_credit), - "closing_balance": str(total_closing) + "closing_balance": str(total_closing), + "ratio": "100.00" }, - "accounts": result_accounts + "accounts": result_accounts, + "grand_total_closing": str(grand_total_closing) } diff --git a/backend/app/routers/trial_balance.py b/backend/app/routers/trial_balance.py index 375d12b..5a6ffdd 100644 --- a/backend/app/routers/trial_balance.py +++ b/backend/app/routers/trial_balance.py @@ -23,7 +23,7 @@ def get_trial_balance( COALESCE(SUM(l.debit), 0) AS debit, COALESCE(SUM(l.credit), 0) AS credit FROM journal_lines l - JOIN journal_entries e ON e.journal_id = l.journal_id + JOIN journal_entries e ON e.journal_entry_id = l.journal_entry_id JOIN accounts a ON a.account_id = l.account_id WHERE 1 = 1 """ diff --git a/backend/sql/insert_opening_balances_2024.sql b/backend/sql/insert_opening_balances_2024.sql new file mode 100644 index 0000000..5f985c9 --- /dev/null +++ b/backend/sql/insert_opening_balances_2024.sql @@ -0,0 +1,50 @@ +-- 2024年度(2024年6月1日~2025年5月31日)期首残高データ +-- ★残高試算表_20250724.pdfより + +-- 既存データを削除(2024年度のみ) +DELETE FROM opening_balances WHERE fiscal_year = 2024; + +-- 期首残高データの挿入 +INSERT INTO opening_balances (fiscal_year, account_id, opening_debit, opening_credit) VALUES +-- 現金(101) +(2024, (SELECT account_id FROM accounts WHERE account_code = '101'), 878375, 0), + +-- 普通預金(102)- UFJ/0788058 として登録 +(2024, (SELECT account_id FROM accounts WHERE account_code = '102'), 11246013, 0), + +-- 売掛金(201) +(2024, (SELECT account_id FROM accounts WHERE account_code = '201'), 5269872, 0), + +-- 仮払金(203) +(2024, (SELECT account_id FROM accounts WHERE account_code = '203'), 1284834, 0), + +-- 買掛金(501) +(2024, (SELECT account_id FROM accounts WHERE account_code = '501'), 0, 9933067), + +-- 未払金(502) +(2024, (SELECT account_id FROM accounts WHERE account_code = '502'), 0, 840000), + +-- 未払法人税等(504) +(2024, (SELECT account_id FROM accounts WHERE account_code = '504'), 0, 94700), + +-- 未払消費税等(505) +(2024, (SELECT account_id FROM accounts WHERE account_code = '505'), 0, 1498400), + +-- 預り金(506) +(2024, (SELECT account_id FROM accounts WHERE account_code = '506'), 0, 61300), + +-- 資本金(601) +(2024, (SELECT account_id FROM accounts WHERE account_code = '601'), 0, 6000000); + +-- 繰越利益剰余金(602)は自動計算されるため入力不要 + +-- 確認用クエリ +SELECT + a.account_code, + a.account_name, + ob.opening_debit, + ob.opening_credit +FROM opening_balances ob +JOIN accounts a ON ob.account_id = a.account_id +WHERE ob.fiscal_year = 2024 +ORDER BY a.account_code; diff --git a/backend/sql/insert_opening_balances_2025.sql b/backend/sql/insert_opening_balances_2025.sql new file mode 100644 index 0000000..fdc31f4 --- /dev/null +++ b/backend/sql/insert_opening_balances_2025.sql @@ -0,0 +1,67 @@ +-- 既存の期首残高データを削除 +DELETE FROM opening_balances; + +-- 2025年度(2025年6月1日~2026年5月31日)期首残高データ +-- ★残高試算表_20250724.pdf の「当期残高」列より(2025年5月31日時点) + +INSERT INTO opening_balances (fiscal_year, account_id, opening_debit, opening_credit) VALUES +-- 現金(101): 0 + +-- 普通預金(102): 3,231,129 +(2025, (SELECT account_id FROM accounts WHERE account_code = '102'), 3231129, 0), + +-- 売掛金(201): 3,083,000 +(2025, (SELECT account_id FROM accounts WHERE account_code = '201'), 3083000, 0), + +-- 未収入金(202): 17,842,822(短期貸付金の代わり) +(2025, (SELECT account_id FROM accounts WHERE account_code = '202'), 17842822, 0), + +-- 前渡金(203 仮払金): 387,400 +(2025, (SELECT account_id FROM accounts WHERE account_code = '203'), 387400, 0), + +-- 工具器具備品(406): 345,383 +(2025, (SELECT account_id FROM accounts WHERE account_code = '406'), 345383, 0), + +-- 差入保証金(410): 220,000 +(2025, (SELECT account_id FROM accounts WHERE account_code = '410'), 220000, 0), + +-- 買掛金(501): 9,376,260(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '501'), 0, 9376260), + +-- 未払金(502): 0 + +-- 未払費用(503): 1,087,312(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '503'), 0, 1087312), + +-- 未払法人税等(504): 1,525,500(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '504'), 0, 1525500), + +-- 未払消費税等(505): 1,245,200(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '505'), 0, 1245200), + +-- 預り金(506): 669,316(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '506'), 0, 669316), + +-- 資本金(601): 6,000,000(貸方) +(2025, (SELECT account_id FROM accounts WHERE account_code = '601'), 0, 6000000); + +-- 繰越利益剰余金(602): 5,206,146 は自動計算されるため入力不要 + +-- 確認用クエリ +SELECT + a.account_code, + a.account_name, + ob.opening_debit, + ob.opening_credit +FROM opening_balances ob +JOIN accounts a ON ob.account_id = a.account_id +WHERE ob.fiscal_year = 2025 +ORDER BY a.account_code; + +-- 合計確認 +SELECT + SUM(opening_debit) as total_debit, + SUM(opening_credit) as total_credit, + SUM(opening_debit) - SUM(opening_credit) as diff +FROM opening_balances +WHERE fiscal_year = 2025; diff --git a/frontend/journal-entry.html b/frontend/journal-entry.html index a687bc6..5d31e44 100644 --- a/frontend/journal-entry.html +++ b/frontend/journal-entry.html @@ -52,7 +52,13 @@
| 日付 | +摘要 | +借方合計 | +貸方合計 | +操作 | +
|---|