修正
This commit is contained in:
Binary file not shown.
@@ -42,3 +42,6 @@ app.include_router(ledger_router)
|
||||
from app.modules.trial_balance.router import router as trial_balance_router
|
||||
app.include_router(trial_balance_router)
|
||||
|
||||
from app.modules.opening_balances.router import router as opening_router
|
||||
app.include_router(opening_router)
|
||||
|
||||
|
||||
29
backend/app/modules/journals/schemas.py
Normal file
29
backend/app/modules/journals/schemas.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# app/modules/journals/schemas.py
|
||||
from pydantic import BaseModel, field_validator
|
||||
from typing import List
|
||||
from decimal import Decimal
|
||||
from datetime import date
|
||||
|
||||
class JournalLineCreate(BaseModel):
|
||||
account_id: int
|
||||
debit: Decimal = 0
|
||||
credit: Decimal = 0
|
||||
|
||||
@field_validator("debit", "credit")
|
||||
@classmethod
|
||||
def non_negative(cls, v):
|
||||
if v < 0:
|
||||
raise ValueError("金額は0以上で入力してください")
|
||||
return v
|
||||
|
||||
class JournalCreate(BaseModel):
|
||||
journal_date: date
|
||||
description: str
|
||||
lines: List[JournalLineCreate]
|
||||
|
||||
@field_validator("lines")
|
||||
@classmethod
|
||||
def validate_lines(cls, v):
|
||||
if len(v) < 2:
|
||||
raise ValueError("仕訳明細は2行以上必要です")
|
||||
return v
|
||||
0
backend/app/modules/opening_balances/__init__.py
Normal file
0
backend/app/modules/opening_balances/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
55
backend/app/modules/opening_balances/router.py
Normal file
55
backend/app/modules/opening_balances/router.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# backend/app/modules/opening_balances/router.py
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from psycopg.errors import ForeignKeyViolation
|
||||
from app.core.database import get_connection
|
||||
from app.modules.opening_balances.schema import OpeningBalanceCreate
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/opening-balances",
|
||||
tags=["期首残高"]
|
||||
)
|
||||
|
||||
@router.post("/", summary="期首残高 登録/更新")
|
||||
def upsert_opening_balance(data: OpeningBalanceCreate):
|
||||
try:
|
||||
with get_connection() as conn, conn.cursor() as cur:
|
||||
cur.execute("""
|
||||
INSERT INTO opening_balances
|
||||
(fiscal_year, account_id, opening_debit, opening_credit)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
ON CONFLICT (fiscal_year, account_id)
|
||||
DO UPDATE SET
|
||||
opening_debit = EXCLUDED.opening_debit,
|
||||
opening_credit = EXCLUDED.opening_credit
|
||||
""", (
|
||||
data.fiscal_year,
|
||||
data.account_id,
|
||||
data.opening_debit,
|
||||
data.opening_credit
|
||||
))
|
||||
conn.commit()
|
||||
return {"result": "ok"}
|
||||
|
||||
except ForeignKeyViolation:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="存在しない科目が指定されています"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{fiscal_year}", summary="期首残高一覧取得")
|
||||
def list_opening_balances(fiscal_year: int):
|
||||
with get_connection() as conn, conn.cursor() as cur:
|
||||
cur.execute("""
|
||||
SELECT
|
||||
a.account_code,
|
||||
a.account_name,
|
||||
a.account_type,
|
||||
ob.opening_debit,
|
||||
ob.opening_credit
|
||||
FROM opening_balances ob
|
||||
JOIN accounts a ON a.account_id = ob.account_id
|
||||
WHERE ob.fiscal_year = %s
|
||||
ORDER BY a.account_code
|
||||
""", (fiscal_year,))
|
||||
return cur.fetchall()
|
||||
25
backend/app/modules/opening_balances/schema.py
Normal file
25
backend/app/modules/opening_balances/schema.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# backend/app/modules/opening_balances/schema.py
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
class OpeningBalanceCreate(BaseModel):
|
||||
fiscal_year: int
|
||||
account_id: int
|
||||
opening_debit: float = 0
|
||||
opening_credit: float = 0
|
||||
|
||||
@field_validator("fiscal_year")
|
||||
@classmethod
|
||||
def validate_year(cls, v: int):
|
||||
if v < 2000 or v > 2100:
|
||||
raise ValueError("会计年度不正确")
|
||||
return v
|
||||
|
||||
@field_validator("opening_credit")
|
||||
@classmethod
|
||||
def validate_balance(cls, v, info):
|
||||
debit = info.data.get("opening_debit", 0)
|
||||
if debit > 0 and v > 0:
|
||||
raise ValueError("借方和贷方不能同时输入金额")
|
||||
if debit < 0 or v < 0:
|
||||
raise ValueError("金额不能为负数")
|
||||
return v
|
||||
Reference in New Issue
Block a user