from datetime import date from typing import Literal from pydantic import BaseModel, ConfigDict, Field, field_validator from pydantic.alias_generators import to_camel from module_business.entity.vo.operation_vo import PositiveId, ShipmentItemModel, ShipmentModel, ShipmentPageQueryModel class ShipmentReceiptCommandModel(BaseModel): model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True, extra='forbid') scanned_pallet_ids: list[PositiveId] = Field(min_length=1, description='实际核对的托盘集合') idempotency_key: str = Field(min_length=1, max_length=64, pattern=r'\S') @field_validator('scanned_pallet_ids') @classmethod def unique_pallets(cls, value: list[int]) -> list[int]: if len(value) != len(set(value)): raise ValueError('核对托盘不能重复') return value class ShipmentReceiptQueryModel(ShipmentPageQueryModel): receipt_state: Literal['PENDING', 'RECEIVED', 'LEGACY'] | None = None class ShipmentReceiptItemModel(ShipmentItemModel): pallet_code: str = Field(description='原托盘号') qr_token: str = Field(description='规范二维码标识') strain_name: str | None = None batch_no: str | None = None production_date: date | None = None expiry_date: date | None = None class ShipmentReceiptModel(ShipmentModel): items: list[ShipmentReceiptItemModel] = Field(default_factory=list)