217 lines
7.3 KiB
Python
217 lines
7.3 KiB
Python
"""
|
|
API路由 - 财务核算
|
|
"""
|
|
from typing import Annotated, Optional
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.database import get_db
|
|
from app.core.security import get_current_active_user, get_current_manager_user
|
|
from app.schemas.schemas import (
|
|
FinanceRecordCreate, FinanceRecordUpdate, FinanceRecordResponse,
|
|
DepartmentBalance, CategorySummary, ResponseBase
|
|
)
|
|
from app.services.finance_service import FinanceService
|
|
from app.models.finance import RevenueCategory, ExpenseCategory, FinanceType
|
|
from app.models.models import User
|
|
|
|
router = APIRouter(prefix="/finance", tags=["财务核算"])
|
|
|
|
|
|
@router.get("/revenue", summary="获取科室收入")
|
|
async def get_revenue(
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取科室收入列表"""
|
|
data = await FinanceService.get_department_revenue(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/expense", summary="获取科室支出")
|
|
async def get_expense(
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取科室支出列表"""
|
|
data = await FinanceService.get_department_expense(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/balance", summary="获取收支结余")
|
|
async def get_balance(
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取科室收支结余"""
|
|
data = await FinanceService.get_department_balance(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/revenue/by-category", summary="按类别统计收入")
|
|
async def get_revenue_by_category(
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""按类别统计收入"""
|
|
data = await FinanceService.get_revenue_by_category(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/expense/by-category", summary="按类别统计支出")
|
|
async def get_expense_by_category(
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""按类别统计支出"""
|
|
data = await FinanceService.get_expense_by_category(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/summary", summary="获取科室财务汇总")
|
|
async def get_department_summary(
|
|
period_year: int = Query(..., description="年度"),
|
|
period_month: int = Query(..., ge=1, le=12, description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取所有科室的财务汇总"""
|
|
data = await FinanceService.get_department_summary(
|
|
db, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": data
|
|
}
|
|
|
|
|
|
@router.get("/categories", summary="获取财务类别")
|
|
async def get_categories(
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取收入和支出类别"""
|
|
revenue_categories = [
|
|
{"value": cat.value, "label": label}
|
|
for cat, label in FinanceService.REVENUE_LABELS.items()
|
|
]
|
|
expense_categories = [
|
|
{"value": cat.value, "label": label}
|
|
for cat, label in FinanceService.EXPENSE_LABELS.items()
|
|
]
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": {
|
|
"revenue": revenue_categories,
|
|
"expense": expense_categories
|
|
}
|
|
}
|
|
|
|
|
|
@router.post("", summary="创建财务记录")
|
|
async def create_finance_record(
|
|
record_data: FinanceRecordCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""创建财务记录(需要管理员或经理权限)"""
|
|
# 验证类别
|
|
if record_data.finance_type == FinanceType.REVENUE:
|
|
valid_categories = [cat.value for cat in RevenueCategory]
|
|
else:
|
|
valid_categories = [cat.value for cat in ExpenseCategory]
|
|
|
|
if record_data.category not in valid_categories:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"无效的类别: {record_data.category}"
|
|
)
|
|
|
|
record = await FinanceService.create_finance_record(
|
|
db,
|
|
department_id=record_data.department_id,
|
|
finance_type=record_data.finance_type,
|
|
category=record_data.category,
|
|
amount=record_data.amount,
|
|
period_year=record_data.period_year,
|
|
period_month=record_data.period_month,
|
|
source=record_data.source,
|
|
remark=record_data.remark
|
|
)
|
|
return {"code": 200, "message": "创建成功", "data": {"id": record.id}}
|
|
|
|
|
|
@router.put("/{record_id}", summary="更新财务记录")
|
|
async def update_finance_record(
|
|
record_id: int,
|
|
record_data: FinanceRecordUpdate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""更新财务记录(需要管理员或经理权限)"""
|
|
record = await FinanceService.update_finance_record(
|
|
db, record_id, **record_data.model_dump(exclude_unset=True)
|
|
)
|
|
if not record:
|
|
raise HTTPException(status_code=404, detail="财务记录不存在")
|
|
return {"code": 200, "message": "更新成功"}
|
|
|
|
|
|
@router.delete("/{record_id}", summary="删除财务记录")
|
|
async def delete_finance_record(
|
|
record_id: int,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""删除财务记录(需要管理员或经理权限)"""
|
|
success = await FinanceService.delete_finance_record(db, record_id)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="财务记录不存在")
|
|
return {"code": 200, "message": "删除成功"}
|