- 新規モジュール: backend/app/payroll/withholding_slip/ - schemas.py: 源泉徴収票データモデル - service.py: 年間集計・給与所得控除・控除額計算ロジック - router.py: POST /payroll/withholding-slip/generate - frontend/withholding-slip.html: 票面プレビュー・印刷(3部)ページ - frontend/payroll.html: 源泉徴収票メニューカード追加 - backend/app/main.py: ルーター登録
72 lines
2.7 KiB
Python
72 lines
2.7 KiB
Python
"""
|
|
給与所得の源泉徴収票 APIルーター
|
|
"""
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from typing import List, Optional
|
|
import logging
|
|
|
|
from .schemas import WithholdingSlipRequest, WithholdingSlipResponse
|
|
from .service import get_withholding_slips
|
|
from app.core.database import get_connection
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/payroll/withholding-slip", tags=["Payroll - Withholding Slip"])
|
|
|
|
|
|
@router.post("/generate", response_model=WithholdingSlipResponse)
|
|
def generate_withholding_slips(request: WithholdingSlipRequest):
|
|
"""
|
|
指定年度・従業員の給与所得の源泉徴収票データを生成する
|
|
"""
|
|
if not request.employee_ids:
|
|
raise HTTPException(status_code=400, detail="従業員IDを指定してください")
|
|
if request.tax_year < 2000 or request.tax_year > 2099:
|
|
raise HTTPException(status_code=400, detail="年度が不正です")
|
|
|
|
try:
|
|
slips = get_withholding_slips(request.tax_year, request.employee_ids)
|
|
return WithholdingSlipResponse(
|
|
tax_year=request.tax_year,
|
|
slips=slips,
|
|
total_count=len(slips)
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"源泉徴収票生成エラー: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.get("/employees")
|
|
def get_employees_for_slip():
|
|
"""アクティブな従業員リストを取得(源泉徴収票用)"""
|
|
try:
|
|
with get_connection() as conn:
|
|
with conn.cursor() as cur:
|
|
cur.execute("""
|
|
SELECT employee_id, employee_code, name, name_kana
|
|
FROM employees
|
|
WHERE is_active = true
|
|
ORDER BY employee_code
|
|
""")
|
|
rows = cur.fetchall()
|
|
result = []
|
|
for row in rows:
|
|
if isinstance(row, dict):
|
|
result.append({
|
|
"id": row["employee_id"],
|
|
"code": row["employee_code"],
|
|
"name": row["name"],
|
|
"name_kana": row.get("name_kana", "")
|
|
})
|
|
else:
|
|
result.append({
|
|
"id": row[0],
|
|
"code": row[1],
|
|
"name": row[2],
|
|
"name_kana": row[3] if len(row) > 3 else ""
|
|
})
|
|
return {"employees": result, "total": len(result)}
|
|
except Exception as e:
|
|
logger.error(f"従業員リスト取得エラー: {e}")
|
|
raise HTTPException(status_code=500, detail=str(e))
|