修正
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
|
from app.modules.trial_balance.router import router as trial_balance_router
|
||||||
app.include_router(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