"""正式工资核算的最小输入契约;金额使用字符串,资料版本显式校验。""" 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 @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)