from datetime import datetime from pydantic import BaseModel, ConfigDict, Field from pydantic.alias_generators import to_camel from module_business.domain.enums import DocumentStatus, PalletEventType, PalletFlowState, ReturnStatus class PalletInventoryReportQueryModel(BaseModel): """托盘库存报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') flow_state: PalletFlowState | None = Field(default=None, description='托盘流转状态') warehouse_id: int | None = Field(default=None, gt=0, description='仓库ID') site_id: int | None = Field(default=None, gt=0, description='现场ID') line_id: int | None = Field(default=None, gt=0, description='产线ID') strain_id: int | None = Field(default=None, gt=0, description='菌种ID') batch_no: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='生产批次') class PalletInventoryReportModel(BaseModel): """托盘库存报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') flow_state: PalletFlowState = Field(description='托盘流转状态') warehouse_id: int | None = Field(default=None, gt=0, description='当前仓库ID') warehouse_name: str | None = Field(default=None, max_length=100, description='当前仓库名称') site_id: int | None = Field(default=None, gt=0, description='当前现场ID') site_name: str | None = Field(default=None, max_length=100, description='当前现场名称') line_id: int | None = Field(default=None, gt=0, description='当前产线ID') line_name: str | None = Field(default=None, max_length=100, description='当前产线名称') strain_id: int | None = Field(default=None, gt=0, description='当前菌种ID') strain_code: str | None = Field(default=None, max_length=64, description='当前菌种编码快照') strain_name: str | None = Field(default=None, max_length=100, description='当前菌种名称快照') batch_no: str | None = Field(default=None, max_length=64, description='当前生产批次') initial_packages: int | None = Field(default=None, strict=True, gt=0, description='初始包数') remaining_packages: int = Field(strict=True, ge=0, description='当前剩余包数') updated_at: datetime = Field(description='库存更新时间') class FillingReportQueryModel(BaseModel): """装填记录报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') warehouse_id: int | None = Field(default=None, gt=0, description='仓库ID') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') strain_id: int | None = Field(default=None, gt=0, description='菌种ID') batch_no: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='生产批次') class FillingReportModel(BaseModel): """装填记录报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) filling_id: int = Field(gt=0, description='装填记录ID') filling_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='装填单号') operated_at: datetime = Field(description='装填时间') warehouse_id: int = Field(gt=0, description='仓库ID') warehouse_name: str | None = Field(default=None, max_length=100, description='仓库名称') pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') strain_id: int = Field(gt=0, description='菌种ID') strain_code_snapshot: str = Field(min_length=1, max_length=64, pattern=r'\S', description='菌种编码快照') strain_name_snapshot: str = Field(min_length=1, max_length=100, pattern=r'\S', description='菌种名称快照') batch_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='生产批次') package_spec: str = Field(min_length=1, max_length=64, pattern=r'\S', description='包装规格') initial_packages: int = Field(strict=True, gt=0, description='初始包数') operator_id: int = Field(gt=0, description='操作人ID') operator_name: str | None = Field(default=None, max_length=100, description='操作人名称') class ShipmentReportQueryModel(BaseModel): """发货出库报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') shipment_no: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='发货单号') source_warehouse_id: int | None = Field(default=None, gt=0, description='来源仓库ID') target_site_id: int | None = Field(default=None, gt=0, description='目标现场ID') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') status: DocumentStatus | None = Field(default=None, description='单据状态') class ShipmentReportModel(BaseModel): """发货出库报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) shipment_id: int = Field(gt=0, description='发货单ID') shipment_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='发货单号') confirmed_at: datetime = Field(description='确认发货时间') source_warehouse_id: int = Field(gt=0, description='来源仓库ID') source_warehouse_name: str | None = Field(default=None, max_length=100, description='来源仓库名称') target_site_id: int = Field(gt=0, description='目标现场ID') target_site_name: str | None = Field(default=None, max_length=100, description='目标现场名称') customer_id: int = Field(gt=0, description='客户ID') customer_name: str | None = Field(default=None, max_length=100, description='客户名称') pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') active_filling_id: int | None = Field(default=None, gt=0, description='发货时活动装填记录ID') package_qty: int = Field(strict=True, gt=0, description='发货时包数快照') class ConsumptionReportQueryModel(BaseModel): """产线消耗报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') customer_id: int | None = Field(default=None, gt=0, description='客户ID') site_id: int | None = Field(default=None, gt=0, description='现场ID') line_id: int | None = Field(default=None, gt=0, description='产线ID') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') strain_id: int | None = Field(default=None, gt=0, description='菌种ID') batch_no: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='生产批次') class ConsumptionReportModel(BaseModel): """产线消耗报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) usage_id: int = Field(gt=0, description='使用记录ID') usage_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='使用记录号') occurred_at: datetime = Field(description='使用发生时间') customer_id: int = Field(gt=0, description='客户ID') customer_name: str | None = Field(default=None, max_length=100, description='客户名称') site_id: int = Field(gt=0, description='现场ID') site_name: str | None = Field(default=None, max_length=100, description='现场名称') line_id: int = Field(gt=0, description='产线ID') line_name: str | None = Field(default=None, max_length=100, description='产线名称') pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') strain_id: int = Field(gt=0, description='菌种ID') strain_code: str | None = Field(default=None, max_length=64, description='菌种编码快照') strain_name: str | None = Field(default=None, max_length=100, description='菌种名称快照') batch_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='生产批次') used_packages: int = Field(strict=True, gt=0, description='本次使用包数') remaining_packages_after: int = Field(strict=True, ge=0, description='使用后剩余包数') operator_id: int = Field(gt=0, description='操作人ID') operator_name: str | None = Field(default=None, max_length=100, description='操作人名称') class ReturnReportQueryModel(BaseModel): """退回仓库报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') return_no: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='退回单号') source_site_id: int | None = Field(default=None, gt=0, description='来源现场ID') target_warehouse_id: int | None = Field(default=None, gt=0, description='目标仓库ID') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') status: ReturnStatus | None = Field(default=None, description='退回状态') class ReturnReportModel(BaseModel): """退回仓库报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) return_id: int = Field(gt=0, description='退回单ID') return_no: str = Field(min_length=1, max_length=64, pattern=r'\S', description='退回单号') status: ReturnStatus = Field(description='退回状态') requested_at: datetime = Field(description='申请时间') confirmed_at: datetime | None = Field(default=None, description='确认时间') source_site_id: int = Field(gt=0, description='来源现场ID') source_site_name: str | None = Field(default=None, max_length=100, description='来源现场名称') target_warehouse_id: int = Field(gt=0, description='目标仓库ID') target_warehouse_name: str | None = Field(default=None, max_length=100, description='目标仓库名称') pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') active_filling_id_snapshot: int | None = Field(default=None, gt=0, description='活动装填记录快照') remaining_packages_snapshot: int = Field(strict=True, ge=0, description='剩余包数快照') class PalletTraceReportQueryModel(BaseModel): """托盘追溯报表查询模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) page_num: int = Field(default=1, gt=0, description='当前页码') page_size: int = Field(default=10, gt=0, description='每页记录数') begin_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='开始时间') end_time: str | None = Field(default=None, min_length=1, pattern=r'\S', description='结束时间') pallet_code: str | None = Field(default=None, min_length=1, max_length=64, pattern=r'\S', description='托盘编号') event_type: PalletEventType | None = Field(default=None, description='事件类型') class PalletTraceReportModel(BaseModel): """托盘追溯报表行模型。""" model_config = ConfigDict(alias_generator=to_camel, from_attributes=True, populate_by_name=True) event_id: int = Field(gt=0, description='事件ID') event_seq: int = Field(gt=0, description='托盘内事件序号') event_type: PalletEventType = Field(description='事件类型') source_type: str = Field(min_length=1, max_length=32, pattern=r'\S', description='来源类型') source_id: int = Field(gt=0, description='来源记录ID') pallet_id: int = Field(gt=0, description='托盘ID') pallet_code: str = Field(min_length=1, max_length=64, pattern=r'\S', description='托盘编号') before_state: PalletFlowState = Field(description='变更前状态') after_state: PalletFlowState = Field(description='变更后状态') before_warehouse_id: int | None = Field(default=None, gt=0, description='变更前仓库ID') before_warehouse_name: str | None = Field(default=None, max_length=100, description='变更前仓库名称') before_site_id: int | None = Field(default=None, gt=0, description='变更前现场ID') before_site_name: str | None = Field(default=None, max_length=100, description='变更前现场名称') before_line_id: int | None = Field(default=None, gt=0, description='变更前产线ID') before_line_name: str | None = Field(default=None, max_length=100, description='变更前产线名称') after_warehouse_id: int | None = Field(default=None, gt=0, description='变更后仓库ID') after_warehouse_name: str | None = Field(default=None, max_length=100, description='变更后仓库名称') after_site_id: int | None = Field(default=None, gt=0, description='变更后现场ID') after_site_name: str | None = Field(default=None, max_length=100, description='变更后现场名称') after_line_id: int | None = Field(default=None, gt=0, description='变更后产线ID') after_line_name: str | None = Field(default=None, max_length=100, description='变更后产线名称') before_remaining_packages: int = Field(strict=True, ge=0, description='变更前剩余包数') after_remaining_packages: int = Field(strict=True, ge=0, description='变更后剩余包数') operator_id: int = Field(gt=0, description='操作人ID') operator_name: str | None = Field(default=None, max_length=100, description='操作人名称') occurred_at: datetime = Field(description='发生时间')