PayrollManagementSystem/backend/app/schemas/payroll.py
liuwenxin 1e53792ad6 feat(T+): 完成数据贯通与自动接入闭环
打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。
新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。
补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
2026-11-05 18:47:13 +08:00

68 lines
2.0 KiB
Python

"""正式工资核算的最小输入契约;金额使用字符串,资料版本显式校验。"""
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator
from app.core.month import validate_month
from app.schemas.tplus_workbench import HandoverFact, _decimal
class PayrollMonthIn(BaseModel):
month: str
reason: str | None = Field(default=None, min_length=1, max_length=255)
@field_validator("month")
@classmethod
def check_month(cls, value):
return validate_month(value)
class ShipmentOwnershipIn(BaseModel):
model_config = ConfigDict(extra="forbid")
shipment_item_id: int = Field(ge=1)
personnel_id: int = Field(ge=1)
manager_id: int | None = Field(default=None, ge=1)
unit_cost: str
freight_amount: str | None = None
@field_validator("freight_amount")
@classmethod
def check_freight(cls, value):
if value is not None:
_decimal(value, 2)
return value
@field_validator("unit_cost")
@classmethod
def check_cost(cls, value):
_decimal(value, 4)
return value
class PayrollSetupIn(PayrollMonthIn):
model_config = ConfigDict(extra="forbid")
expected_version: int = Field(default=0, ge=0)
evidence: str = Field(min_length=1, max_length=500)
opening_balance: str
history_confirmed: Literal[True]
guidance_finalized: Literal[True]
shipment_ownerships: list[ShipmentOwnershipIn] = Field(min_length=1, max_length=10000)
handovers: list[HandoverFact] = Field(default_factory=list, max_length=1000)
@field_validator("opening_balance")
@classmethod
def check_opening(cls, value):
_decimal(value, 2)
return value
class AllocationAdjustmentIn(BaseModel):
"""分配差额仅允许归生成当月;关联已结算原台账留痕。"""
ledger_id: int = Field(ge=1)
personnel_id: int = Field(ge=1)
direction: Literal[1, 2]
amount: str = Field(pattern=r"^\d{1,12}(\.\d{1,2})?$")
reason: str = Field(min_length=1, max_length=255)