"""月度结算接口(M3 ④):生成/提交审批/锁定与调整单。 准入:读=登录即可;写(生成/提交/调整单)=管理员与营销后勤 (权限清单待澄清 #6,答复后细化)。 """ from typing import Annotated from fastapi import APIRouter, Depends, Path, Query from app.api.deps import DbSession, RequestMetaDep, require_roles from app.core.constants import ROLE_ADMIN, ROLE_MARKETING_OPS from app.core.response import ApiResponse, PageResult, ok from app.models import User from app.schemas.settlement import ( AdjustmentCreateIn, SettlementDetailOut, SettlementGenerateIn, SettlementOut, SettlementQuery, ) from app.services import settlement_service router = APIRouter(prefix="/settlements", tags=["绩效工资 · 月度结算"]) _SettlementWriter = Annotated[User, Depends(require_roles(ROLE_ADMIN, ROLE_MARKETING_OPS))] @router.post("/generate", response_model=ApiResponse[SettlementDetailOut], summary="生成月结快照") def generate( payload: SettlementGenerateIn, session: DbSession, current_user: _SettlementWriter, 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, current_user: _SettlementWriter, 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, current_user: _SettlementWriter, 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))