2026-10-16 12:33:31 -04:00
|
|
|
|
"""月度结算的请求/响应模型(M3 ④)。"""
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
|
|
|
2026-10-19 21:44:43 -04:00
|
|
|
|
from app.core.month import validate_month
|
2026-10-16 12:33:31 -04:00
|
|
|
|
from app.core.response import PageQuery
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _check_month(value: str) -> str:
|
2026-10-19 21:44:43 -04:00
|
|
|
|
"""月份格式 YYYY-MM 且月份 01-12(settlement_month 全表唯一的维度)。"""
|
|
|
|
|
|
return validate_month(value)
|
2026-10-16 12:33:31 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SettlementGenerateIn(BaseModel):
|
|
|
|
|
|
"""月结生成入参。"""
|
|
|
|
|
|
|
|
|
|
|
|
month: str = Field(description="结算月份 YYYY-MM")
|
|
|
|
|
|
|
|
|
|
|
|
@field_validator("month")
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
def _v_month(cls, value: str) -> str:
|
|
|
|
|
|
return _check_month(value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SettlementQuery(PageQuery):
|
|
|
|
|
|
"""月结列表查询。"""
|
|
|
|
|
|
|
|
|
|
|
|
status: int | None = Field(default=None, ge=1, le=4, description="状态筛选")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SettlementItemOut(BaseModel):
|
|
|
|
|
|
"""月结明细行。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
|
|
|
|
|
|
id: int
|
|
|
|
|
|
personnel_id: int
|
|
|
|
|
|
personnel_name: str
|
|
|
|
|
|
role_code: str
|
|
|
|
|
|
calc_type: int
|
|
|
|
|
|
performance_sum: Decimal
|
|
|
|
|
|
payable_sum: Decimal
|
|
|
|
|
|
basic_amount: Decimal | None = None
|
|
|
|
|
|
salary_mode: str | None = None
|
|
|
|
|
|
net_amount: Decimal | None = None
|
|
|
|
|
|
is_probation: int
|
|
|
|
|
|
probation_note: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SettlementOut(BaseModel):
|
|
|
|
|
|
"""月结头表响应。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
|
|
|
|
|
|
id: int
|
|
|
|
|
|
settlement_month: str
|
|
|
|
|
|
status: int
|
|
|
|
|
|
total_performance: Decimal | None = None
|
|
|
|
|
|
total_payable: Decimal | None = None
|
|
|
|
|
|
person_count: int
|
|
|
|
|
|
approval_order_no: str | None = None
|
|
|
|
|
|
submitter_name: str
|
|
|
|
|
|
locked_at: datetime | datetime | None = None
|
|
|
|
|
|
locked_by: str | None = None
|
|
|
|
|
|
create_time: datetime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SettlementDetailOut(SettlementOut):
|
|
|
|
|
|
"""月结详情:附明细。"""
|
|
|
|
|
|
|
|
|
|
|
|
items: list[SettlementItemOut] = Field(default_factory=list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AdjustmentCreateIn(BaseModel):
|
|
|
|
|
|
"""调整单创建入参(金额恒正,方向表达补发/扣减)。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(str_strip_whitespace=True)
|
|
|
|
|
|
|
|
|
|
|
|
settlement_month: str = Field(description="调整月份 YYYY-MM")
|
|
|
|
|
|
personnel_id: int = Field(ge=1, description="调整人员ID")
|
|
|
|
|
|
direction: int = Field(ge=1, le=2, description="1补发 2扣减")
|
2026-10-19 00:10:29 -04:00
|
|
|
|
# 正则先拦格式(非负两位小数、≤12 位整数防 NUMERIC(14,2) 溢出);
|
|
|
|
|
|
# 「> 0」由服务层判定(schema 只管形状,语义校验留在 service)
|
|
|
|
|
|
amount: str = Field(
|
|
|
|
|
|
pattern=r"^\d{1,12}(\.\d{1,2})?$",
|
|
|
|
|
|
description="金额(元,两位小数,恒正)",
|
|
|
|
|
|
)
|
2026-10-16 12:33:31 -04:00
|
|
|
|
reason: str = Field(min_length=1, max_length=255, description="扣补说明")
|
2026-10-19 21:44:43 -04:00
|
|
|
|
|
|
|
|
|
|
@field_validator("settlement_month")
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
def _v_settlement_month(cls, value: str) -> str:
|
|
|
|
|
|
return _check_month(value)
|