"""运输计划管理 - 库存统计 Schema""" from datetime import date, datetime from decimal import Decimal from typing import Optional from pydantic import BaseModel, Field # ============================================================================= # 库存台账 Schema # ============================================================================= class InventoryRead(BaseModel): id: str product_id: str = Field(alias="productId") brand_id: str = Field(default="", alias="brandId") brand_name: Optional[str] = Field(default=None, alias="brandName") product_no: str = Field(alias="productNo") product_name: str = Field(alias="productName") model: Optional[str] = None unit: str stock_qty: Decimal = Field(alias="stockQty") stock_amount: Decimal = Field(alias="stockAmount") low_stock_warning: Optional[Decimal] = Field(default=None, alias="lowStockWarning") high_stock_warning: Optional[Decimal] = Field(default=None, alias="highStockWarning") tenant_no: str = Field(alias="tenantNo") create_time: datetime = Field(alias="createTime") update_time: datetime = Field(alias="updateTime") model_config = {"from_attributes": True, "populate_by_name": True} # ============================================================================= # 库存流水 Schema # ============================================================================= class InventoryTransactionRead(BaseModel): id: str product_id: str = Field(alias="productId") brand_id: str = Field(default="", alias="brandId") brand_name: Optional[str] = Field(default=None, alias="brandName") product_name: str = Field(alias="productName") transaction_type: str = Field(alias="transactionType") plan_id: Optional[str] = Field(default=None, alias="planId") plan_no: Optional[str] = Field(default=None, alias="planNo") qty: Decimal unit_price: Decimal = Field(alias="unitPrice") amount: Decimal stock_after: Decimal = Field(alias="stockAfter") tenant_no: str = Field(alias="tenantNo") create_time: datetime = Field(alias="createTime") model_config = {"from_attributes": True, "populate_by_name": True} # ============================================================================= # 库存预警 Schema # ============================================================================= class InventoryWarningRead(BaseModel): id: str product_id: str = Field(alias="productId") brand_id: str = Field(default="", alias="brandId") brand_name: Optional[str] = Field(default=None, alias="brandName") product_name: str = Field(alias="productName") warning_type: str = Field(alias="warningType") current_qty: Decimal = Field(alias="currentQty") threshold_value: Decimal = Field(alias="thresholdValue") status: str resolve_time: Optional[datetime] = Field(default=None, alias="resolveTime") resolve_remark: Optional[str] = Field(default=None, alias="resolveRemark") tenant_no: str = Field(alias="tenantNo") create_time: datetime = Field(alias="createTime") model_config = {"from_attributes": True, "populate_by_name": True} class InventoryWarningUpdate(BaseModel): status: str = Field(..., description="状态 pending/resolved") resolve_remark: Optional[str] = Field(default=None, alias="resolveRemark", description="处理备注") model_config = {"populate_by_name": True} class InventoryWarningThreshold(BaseModel): product_id: str = Field(..., alias="productId", description="产品ID") brand_id: str = Field(default="", alias="brandId", description="品牌ID,无品牌为空串") brand_name: Optional[str] = Field(default=None, alias="brandName", description="品牌名称") low_stock_warning: Optional[Decimal] = Field(default=None, alias="lowStockWarning", description="最低库存预警值") high_stock_warning: Optional[Decimal] = Field(default=None, alias="highStockWarning", description="最高库存预警值") model_config = {"populate_by_name": True} # ============================================================================= # 证件到期提醒 Schema # ============================================================================= class DocumentReminderRead(BaseModel): id: str cert_id: Optional[str] = Field(default=None, alias="certId") owner_type: Optional[str] = Field(default=None, alias="ownerType") owner_id: Optional[str] = Field(default=None, alias="ownerId") owner_label: Optional[str] = Field(default=None, alias="ownerLabel") driver_id: Optional[str] = Field(default=None, alias="driverId") driver_name: Optional[str] = Field(default=None, alias="driverName") document_type: str = Field(alias="documentType") document_no: Optional[str] = Field(default=None, alias="documentNo") expire_date: date = Field(alias="expireDate") days_remaining: int = Field(alias="daysRemaining") status: str tenant_no: str = Field(alias="tenantNo") create_time: datetime = Field(alias="createTime") model_config = {"from_attributes": True, "populate_by_name": True} class DocumentReminderUpdate(BaseModel): status: str = Field(..., description="状态 pending/resolved") remark: Optional[str] = None model_config = {"populate_by_name": True} class DocumentReminderStatsRead(BaseModel): expired_pending_count: int = Field(alias="expiredPendingCount") model_config = {"populate_by_name": True} # ============================================================================= # 查询参数 # ============================================================================= class InventoryLedgerQuery(BaseModel): product_name: Optional[str] = Field(default=None, alias="productName", description="产品名称") page: int = Field(default=1, ge=1) page_size: int = Field(default=20, ge=1, le=500, alias="pageSize") model_config = {"populate_by_name": True} class InventoryLedgerResponse(BaseModel): total: int list: list[InventoryRead] class InventoryTransactionQuery(BaseModel): product_id: Optional[str] = Field(default=None, alias="productId", description="产品ID") transaction_type: Optional[str] = Field(default=None, alias="transactionType", description="事务类型 inbound/outbound") date_from: Optional[date] = Field(default=None, alias="dateFrom", description="开始日期") date_to: Optional[date] = Field(default=None, alias="dateTo", description="结束日期") page: int = Field(default=1, ge=1) page_size: int = Field(default=20, ge=1, le=500, alias="pageSize") model_config = {"populate_by_name": True} class InventoryTransactionResponse(BaseModel): total: int list: list[InventoryTransactionRead] class InventorySummaryQuery(BaseModel): group_by: str = Field(default="month", alias="groupBy", description="汇总维度 month/week") date_from: date = Field(..., alias="dateFrom", description="开始日期") date_to: date = Field(..., alias="dateTo", description="结束日期") product_id: Optional[str] = Field(default=None, alias="productId", description="产品ID") model_config = {"populate_by_name": True} class InventorySummaryItem(BaseModel): period: str product_id: Optional[str] = Field(default=None, alias="productId") product_name: str = Field(alias="productName") inbound_qty: Decimal = Field(alias="inboundQty") outbound_qty: Decimal = Field(alias="outboundQty") net_change: Decimal = Field(alias="netChange") class InventorySummaryResponse(BaseModel): list: list[InventorySummaryItem] class TransportStatsQuery(BaseModel): group_by: str = Field(default="carrier", alias="groupBy", description="统计维度 carrier/vehicle") date_from: Optional[date] = Field(default=None, alias="dateFrom", description="开始日期") date_to: Optional[date] = Field(default=None, alias="dateTo", description="结束日期") model_config = {"populate_by_name": True} class TransportStatsItem(BaseModel): group_key: str = Field(alias="groupKey") group_name: str = Field(alias="groupName") trip_count: int = Field(alias="tripCount") total_freight: Decimal = Field(alias="totalFreight") class TransportStatsResponse(BaseModel): list: list[TransportStatsItem]