156 lines
6.3 KiB
Python
156 lines
6.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 (
|
|
SalaryRecordCreate, SalaryRecordUpdate, SalaryRecordResponse,
|
|
ResponseBase
|
|
)
|
|
from app.services.salary_service import SalaryService
|
|
from app.models.models import User
|
|
|
|
router = APIRouter(prefix="/salary", tags=["工资核算"])
|
|
|
|
|
|
@router.get("", summary="获取工资记录列表")
|
|
async def get_salary_records(
|
|
staff_id: Optional[int] = Query(None, description="员工ID"),
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
period_year: Optional[int] = Query(None, description="年度"),
|
|
period_month: Optional[int] = Query(None, description="月份"),
|
|
status: Optional[str] = Query(None, description="状态"),
|
|
page: int = Query(1, ge=1, description="页码"),
|
|
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取工资记录列表"""
|
|
records, total = await SalaryService.get_list(
|
|
db, staff_id, department_id, period_year, period_month, status, page, page_size
|
|
)
|
|
|
|
result = []
|
|
for record in records:
|
|
item = SalaryRecordResponse.model_validate(record).model_dump()
|
|
item["staff_name"] = record.staff.name if record.staff else None
|
|
item["department_name"] = record.staff.department.name if record.staff and record.staff.department else None
|
|
result.append(item)
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": result,
|
|
"total": total,
|
|
"page": page,
|
|
"page_size": page_size
|
|
}
|
|
|
|
|
|
@router.get("/{record_id}", summary="获取工资记录详情")
|
|
async def get_salary_record(
|
|
record_id: int,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""获取工资记录详情"""
|
|
record = await SalaryService.get_by_id(db, record_id)
|
|
if not record:
|
|
raise HTTPException(status_code=404, detail="工资记录不存在")
|
|
|
|
result = SalaryRecordResponse.model_validate(record).model_dump()
|
|
result["staff_name"] = record.staff.name if record.staff else None
|
|
result["department_name"] = record.staff.department.name if record.staff and record.staff.department else None
|
|
return {"code": 200, "message": "success", "data": result}
|
|
|
|
|
|
@router.post("", summary="创建工资记录")
|
|
async def create_salary_record(
|
|
record_data: SalaryRecordCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""创建工资记录(需要管理员或经理权限)"""
|
|
record = await SalaryService.create(db, record_data)
|
|
return {"code": 200, "message": "创建成功", "data": {"id": record.id}}
|
|
|
|
|
|
@router.put("/{record_id}", summary="更新工资记录")
|
|
async def update_salary_record(
|
|
record_id: int,
|
|
record_data: SalaryRecordUpdate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""更新工资记录(需要管理员或经理权限)"""
|
|
record = await SalaryService.update(db, record_id, record_data)
|
|
if not record:
|
|
raise HTTPException(status_code=400, detail="无法更新,记录不存在或状态不允许")
|
|
return {"code": 200, "message": "更新成功", "data": {"id": record.id}}
|
|
|
|
|
|
@router.post("/generate", summary="根据考核生成工资")
|
|
async def generate_salary(
|
|
staff_id: int = Query(..., description="员工ID"),
|
|
period_year: int = Query(..., description="年度"),
|
|
period_month: int = Query(..., description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""根据考核记录生成工资记录(需要管理员或经理权限)"""
|
|
record = await SalaryService.generate_from_assessment(
|
|
db, staff_id, period_year, period_month
|
|
)
|
|
if not record:
|
|
raise HTTPException(status_code=400, detail="无法生成,未找到已确认的考核记录或已存在工资记录")
|
|
return {"code": 200, "message": "生成成功", "data": {"id": record.id}}
|
|
|
|
|
|
@router.post("/batch-generate", summary="批量生成工资")
|
|
async def batch_generate_salary(
|
|
department_id: int = Query(..., description="科室ID"),
|
|
period_year: int = Query(..., description="年度"),
|
|
period_month: int = Query(..., description="月份"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""为科室批量生成工资记录(需要管理员或经理权限)"""
|
|
records = await SalaryService.batch_generate_for_department(
|
|
db, department_id, period_year, period_month
|
|
)
|
|
return {
|
|
"code": 200,
|
|
"message": f"成功生成 {len(records)} 条工资记录",
|
|
"data": {"count": len(records)}
|
|
}
|
|
|
|
|
|
@router.post("/{record_id}/confirm", summary="确认工资")
|
|
async def confirm_salary(
|
|
record_id: int,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""确认工资(需要管理员或经理权限)"""
|
|
record = await SalaryService.confirm(db, record_id)
|
|
if not record:
|
|
raise HTTPException(status_code=400, detail="无法确认,记录不存在或状态不允许")
|
|
return {"code": 200, "message": "确认成功"}
|
|
|
|
|
|
@router.post("/batch-confirm", summary="批量确认工资")
|
|
async def batch_confirm_salary(
|
|
period_year: int = Query(..., description="年度"),
|
|
period_month: int = Query(..., description="月份"),
|
|
department_id: Optional[int] = Query(None, description="科室ID"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
|
):
|
|
"""批量确认工资(需要管理员或经理权限)"""
|
|
count = await SalaryService.batch_confirm(db, period_year, period_month, department_id)
|
|
return {"code": 200, "message": f"成功确认 {count} 条工资记录", "data": {"count": count}}
|