import enum from datetime import datetime, date, timezone from decimal import Decimal from sqlalchemy import ( String, Boolean, Date, DateTime, DECIMAL, Integer, Text, ForeignKey, Enum as SAEnum ) from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base class ValuationStatus(str, enum.Enum): bozza = "bozza" inviata = "inviata" in_lavorazione = "in_lavorazione" completata = "completata" vinta = "vinta" persa = "persa" class ValuationPriority(str, enum.Enum): contratto = "contratto" preventivo = "preventivo" valutazione = "valutazione" class RetakeRegime(str, enum.Enum): nuovo = "nuovo" usato = "usato" class Valuation(Base): __tablename__ = "valuations" id: Mapped[int] = mapped_column(Integer, primary_key=True) plate: Mapped[str] = mapped_column(String(10), ForeignKey("vehicle_registry.plate"), nullable=False, index=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False) group_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("groups.id")) motornet_code: Mapped[str | None] = mapped_column(String(20), ForeignKey("vehicle_versions.motornet_code")) mileage: Mapped[int | None] = mapped_column(Integer) retake_regime: Mapped[RetakeRegime | None] = mapped_column(SAEnum(RetakeRegime)) expected_return_date: Mapped[date | None] = mapped_column(Date) interest_fuel: Mapped[str | None] = mapped_column(String(50)) priority: Mapped[ValuationPriority] = mapped_column( SAEnum(ValuationPriority), default=ValuationPriority.valutazione ) notes: Mapped[str | None] = mapped_column(Text) status: Mapped[ValuationStatus] = mapped_column( SAEnum(ValuationStatus), default=ValuationStatus.bozza, index=True ) final_value: Mapped[Decimal | None] = mapped_column(DECIMAL(10, 2)) evaluator_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("users.id")) evaluator_notes: Mapped[str | None] = mapped_column(Text) is_frozen: Mapped[bool] = mapped_column(Boolean, default=False) priority_rank: Mapped[int] = mapped_column(Integer, default=3) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), ) photos: Mapped[list["ValuationPhoto"]] = relationship("ValuationPhoto", back_populates="valuation") comments: Mapped[list["ValuationComment"]] = relationship("ValuationComment", back_populates="valuation") history: Mapped[list["ValuationHistory"]] = relationship("ValuationHistory", back_populates="valuation") contracts: Mapped[list["ValuationContract"]] = relationship("ValuationContract", back_populates="valuation") motornet_valuations: Mapped[list["MotornetValuation"]] = relationship("MotornetValuation", back_populates="valuation") class ValuationPhoto(Base): __tablename__ = "valuation_photos" id: Mapped[int] = mapped_column(Integer, primary_key=True) valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False) filename: Mapped[str] = mapped_column(String(255), nullable=False) storage_path: Mapped[str] = mapped_column(String(500), nullable=False) uploaded_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False) uploaded_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="photos") class ValuationComment(Base): __tablename__ = "valuation_comments" id: Mapped[int] = mapped_column(Integer, primary_key=True) valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False) visible_to_all: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="comments") class ValuationHistory(Base): __tablename__ = "valuation_history" id: Mapped[int] = mapped_column(Integer, primary_key=True) valuation_id: Mapped[int] = mapped_column(Integer, ForeignKey("valuations.id"), nullable=False) changed_by: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False) field_name: Mapped[str] = mapped_column(String(100), nullable=False) old_value: Mapped[str | None] = mapped_column(Text) new_value: Mapped[str | None] = mapped_column(Text) changed_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) valuation: Mapped["Valuation"] = relationship("Valuation", back_populates="history")