import enum import uuid as _uuid from datetime import datetime from decimal import Decimal from sqlalchemy import DateTime, Enum, ForeignKey, Integer, Numeric, String, Text, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base class JobStatus(enum.Enum): queued = "queued" printing = "printing" done = "done" failed = "failed" cancelled = "cancelled" class PrintJob(Base): __tablename__ = "print_jobs" id: Mapped[int] = mapped_column(primary_key=True) job_uuid: Mapped[str | None] = mapped_column(String(36), unique=True, default=lambda: str(_uuid.uuid4())) printer_id: Mapped[int | None] = mapped_column(ForeignKey("printers.id")) filament_id: Mapped[int | None] = mapped_column(ForeignKey("filaments.id")) bracket_id: Mapped[int | None] = mapped_column(ForeignKey("job_brackets.id")) name: Mapped[str] = mapped_column(String(200)) customer: Mapped[str | None] = mapped_column(String(200)) file_name: Mapped[str | None] = mapped_column(String(255)) status: Mapped[JobStatus] = mapped_column(Enum(JobStatus), default=JobStatus.queued) queue_position: Mapped[int | None] = mapped_column(Integer) started_at: Mapped[datetime | None] = mapped_column(DateTime) finished_at: Mapped[datetime | None] = mapped_column(DateTime) duration_minutes: Mapped[int | None] = mapped_column(Integer) filament_used_g: Mapped[Decimal | None] = mapped_column(Numeric(8, 2)) cost_eur: Mapped[Decimal | None] = mapped_column(Numeric(8, 2)) notes: Mapped[str | None] = mapped_column(Text) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( DateTime, server_default=func.now(), onupdate=func.now() ) printer: Mapped["Printer"] = relationship(back_populates="jobs") filament: Mapped["Filament | None"] = relationship(back_populates="jobs") bracket: Mapped["JobBracket | None"] = relationship(back_populates="jobs") logs: Mapped[list["JobLog"]] = relationship( back_populates="job", order_by="JobLog.created_at.desc()" )