"""产品模型""" import uuid from datetime import datetime from sqlalchemy import String, DateTime, ForeignKey from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base from app.core.time_utils import get_beijing_time class Product(Base): __tablename__ = "products" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) serial_number: Mapped[str] = mapped_column( String(16), unique=True, index=True, nullable=False, comment="产品序列号(16位)", ) # ---- 物理外键(关联本库 production_orders)— 可选 ---- order_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("production_orders.id"), nullable=True, comment="所属订单ID(可选)", ) # ---- 外部序列号(用户自定义,可选) ---- external_serial: Mapped[str | None] = mapped_column( String(64), nullable=True, comment="用户自定义产品序列号(可选)", ) # ---- 逻辑外键(关联老系统物料表,仅存储 ID,无物理约束) ---- material_id: Mapped[str | None] = mapped_column( String(64), nullable=True, comment="物料ID(逻辑外键→老系统)", ) # ---- MOM 物料快照字段(创产品时写入,防止老系统数据变动影响标签) ---- material_name: Mapped[str | None] = mapped_column( String(255), nullable=True, comment="物料名称快照", ) spec_model: Mapped[str | None] = mapped_column( String(255), nullable=True, comment="规格型号快照", ) category: Mapped[str | None] = mapped_column( String(255), nullable=True, comment="物料分类快照", ) material_type: Mapped[str | None] = mapped_column( String(100), nullable=True, comment="物料类型快照", ) # ---- 物理外键(自引用:父产品) ---- parent_product_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("products.id"), nullable=True, comment="父产品ID", ) # ---- 当前位置追踪(逻辑外键→用户ID 或 'virtual_warehouse') ---- current_location_id: Mapped[str | None] = mapped_column( String(64), nullable=True, comment="当前持有者ID 或 'virtual_warehouse'(仓库)", ) status: Mapped[str] = mapped_column( String(50), nullable=False, default="pending", comment="产品状态", ) # 宏观流转状态 — 首次扫码时强制设定:备货/生产/测试/维修/在库 overall_status: Mapped[str | None] = mapped_column( String(20), nullable=True, comment="宏观状态: 备货/生产/测试/维修/在库", ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=get_beijing_time, comment="创建时间", ) # ---- 关系 ---- order: Mapped["ProductionOrder"] = relationship("ProductionOrder", lazy="selectin") parent_product: Mapped["Product | None"] = relationship( "Product", remote_side="Product.id", lazy="selectin", ) def __repr__(self) -> str: return f""