""" KPI 項目 Model """ from datetime import datetime from typing import Optional, TYPE_CHECKING from sqlalchemy import String, Integer, DateTime, Text, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base if TYPE_CHECKING: from app.models.kpi_sheet import KPISheet from app.models.kpi_template import KPITemplate class KPIItem(Base): """KPI 項目""" __tablename__ = "KPI_D_items" id: Mapped[int] = mapped_column(primary_key=True) sheet_id: Mapped[int] = mapped_column(ForeignKey("KPI_D_sheets.id", ondelete="CASCADE"), nullable=False) template_id: Mapped[Optional[int]] = mapped_column(ForeignKey("KPI_D_templates.id")) sort_order: Mapped[int] = mapped_column(Integer, default=0) # 項目資訊 name: Mapped[str] = mapped_column(String(200), nullable=False) category: Mapped[str] = mapped_column(String(50), nullable=False) # financial, customer, internal, learning weight: Mapped[int] = mapped_column(Integer, nullable=False) # 權重百分比 (1-100) # 等級標準 level0_criteria: Mapped[Optional[str]] = mapped_column(Text) level1_criteria: Mapped[Optional[str]] = mapped_column(Text) level2_criteria: Mapped[Optional[str]] = mapped_column(Text) level3_criteria: Mapped[Optional[str]] = mapped_column(Text) level4_criteria: Mapped[Optional[str]] = mapped_column(Text) # 自評 self_eval_level: Mapped[Optional[int]] = mapped_column(Integer) # 0-4 self_eval_note: Mapped[Optional[str]] = mapped_column(Text) # 主管評核 final_level: Mapped[Optional[int]] = mapped_column(Integer) # 0-4 final_note: Mapped[Optional[str]] = mapped_column(Text) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Relationships sheet: Mapped["KPISheet"] = relationship("KPISheet", back_populates="items") template: Mapped[Optional["KPITemplate"]] = relationship("KPITemplate", back_populates="kpi_items") def __repr__(self) -> str: return f""