2026-10-16 12:33:31 -04:00
|
|
|
|
"""月度结算接口(M3 ④):生成/提交审批/锁定与调整单。
|
|
|
|
|
|
|
|
|
|
|
|
准入:读=登录即可;写(生成/提交/调整单)=管理员与营销后勤
|
|
|
|
|
|
(权限清单待澄清 #6,答复后细化)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from typing import Annotated
|
|
|
|
|
|
|
|
|
|
|
|
from fastapi import APIRouter, Depends, Path, Query
|
|
|
|
|
|
|
2026-11-01 20:42:53 -05:00
|
|
|
|
from app.api.deps import DbSession, PayrollWriter, RequestMetaDep, get_current_user
|
2026-10-16 12:33:31 -04:00
|
|
|
|
from app.core.response import ApiResponse, PageResult, ok
|
|
|
|
|
|
from app.schemas.settlement import (
|
|
|
|
|
|
AdjustmentCreateIn,
|
|
|
|
|
|
SettlementDetailOut,
|
|
|
|
|
|
SettlementGenerateIn,
|
|
|
|
|
|
SettlementOut,
|
|
|
|
|
|
SettlementQuery,
|
|
|
|
|
|
)
|
|
|
|
|
|
from app.services import settlement_service
|
|
|
|
|
|
|
2026-11-01 20:42:53 -05:00
|
|
|
|
router = APIRouter(dependencies=[Depends(get_current_user)], prefix="/settlements", tags=["绩效工资 · 月度结算"])
|
2026-10-16 12:33:31 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/generate", response_model=ApiResponse[SettlementDetailOut], summary="生成月结快照")
|
|
|
|
|
|
def generate(
|
|
|
|
|
|
payload: SettlementGenerateIn,
|
|
|
|
|
|
session: DbSession,
|
2026-11-01 20:42:53 -05:00
|
|
|
|
current_user: PayrollWriter,
|
2026-10-16 12:33:31 -04:00
|
|
|
|
meta: RequestMetaDep,
|
|
|
|
|
|
) -> ApiResponse[SettlementDetailOut]:
|
|
|
|
|
|
"""按确认回款口径生成指定月份的结算快照(草稿)。"""
|
|
|
|
|
|
return ok(
|
|
|
|
|
|
settlement_service.generate(session, payload.month, operator=current_user, meta=meta),
|
|
|
|
|
|
message="月结已生成",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("", response_model=ApiResponse[PageResult[SettlementOut]], summary="月结列表")
|
|
|
|
|
|
def list_settlements(
|
|
|
|
|
|
session: DbSession,
|
|
|
|
|
|
query: Annotated[SettlementQuery, Query()],
|
|
|
|
|
|
) -> ApiResponse[PageResult[SettlementOut]]:
|
|
|
|
|
|
"""分页查询月结(按月份倒序)。"""
|
|
|
|
|
|
return ok(settlement_service.list_page(session, query))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/{settlement_id}", response_model=ApiResponse[SettlementDetailOut], summary="月结详情")
|
|
|
|
|
|
def get_settlement(
|
|
|
|
|
|
session: DbSession,
|
|
|
|
|
|
settlement_id: Annotated[int, Path(ge=1)],
|
|
|
|
|
|
) -> ApiResponse[SettlementDetailOut]:
|
|
|
|
|
|
"""月结详情(含按人明细)。"""
|
|
|
|
|
|
return ok(settlement_service.get_detail(session, settlement_id))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post(
|
|
|
|
|
|
"/{settlement_id}/submit",
|
|
|
|
|
|
response_model=ApiResponse[SettlementDetailOut],
|
|
|
|
|
|
summary="提交审批",
|
|
|
|
|
|
)
|
|
|
|
|
|
def submit(
|
|
|
|
|
|
settlement_id: Annotated[int, Path(ge=1)],
|
|
|
|
|
|
session: DbSession,
|
2026-11-01 20:42:53 -05:00
|
|
|
|
current_user: PayrollWriter,
|
2026-10-16 12:33:31 -04:00
|
|
|
|
meta: RequestMetaDep,
|
|
|
|
|
|
) -> ApiResponse[SettlementDetailOut]:
|
|
|
|
|
|
"""提交审批:开关关闭=自动通过并锁定;开启=待财务复核。"""
|
|
|
|
|
|
return ok(
|
|
|
|
|
|
settlement_service.submit(session, settlement_id, operator=current_user, meta=meta),
|
|
|
|
|
|
message="已提交",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ==================== 调整单(已锁定月份的补发/扣减) ====================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/adjustments", response_model=ApiResponse[dict], summary="新建调整单")
|
|
|
|
|
|
def create_adjustment(
|
|
|
|
|
|
payload: AdjustmentCreateIn,
|
|
|
|
|
|
session: DbSession,
|
2026-11-01 20:42:53 -05:00
|
|
|
|
current_user: PayrollWriter,
|
2026-10-16 12:33:31 -04:00
|
|
|
|
meta: RequestMetaDep,
|
|
|
|
|
|
) -> ApiResponse[dict]:
|
|
|
|
|
|
"""新建调整单:开关关闭=提交即生效(自动通过留痕);开启=走审批。"""
|
|
|
|
|
|
return ok(
|
|
|
|
|
|
settlement_service.create_adjustment(session, payload, operator=current_user, meta=meta),
|
|
|
|
|
|
message="调整单已创建",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/adjustments", response_model=ApiResponse[list[dict]], summary="调整单列表")
|
|
|
|
|
|
def list_adjustments(session: DbSession) -> ApiResponse[list[dict]]:
|
|
|
|
|
|
"""调整单列表(一期不分页,内部系统量级有限)。"""
|
|
|
|
|
|
return ok(settlement_service.list_adjustments(session))
|