from datetime import datetime, timezone from enum import Enum from typing import TYPE_CHECKING, List, Optional from sqlalchemy import Column, UniqueConstraint from sqlalchemy import Enum as SAEnum from sqlmodel import Field, Relationship, SQLModel from app.models.order_line import OrderLinePublic if TYPE_CHECKING: from app.models.order_line import OrderLine from app.models.participant import Participant from app.models.purchase_round import PurchaseRound class PaymentStatus(str, Enum): UNPAID = "unpaid" PAID = "paid" class OrderBase(SQLModel): payment_status: PaymentStatus = Field( default=PaymentStatus.UNPAID, sa_column=Column( SAEnum( PaymentStatus, name="payment_status", native_enum=False, values_callable=lambda enum_cls: [member.value for member in enum_cls], ), nullable=False, ), ) paid_at: Optional[datetime] = Field(default=None) created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) class Order(OrderBase, table=True): __tablename__ = "orders" __table_args__ = (UniqueConstraint("purchase_round_id", "order_number", name="uq_order_round_order_number"),) id: Optional[int] = Field(default=None, primary_key=True) participant_id: int = Field(foreign_key="participant.id", ondelete="CASCADE") purchase_round_id: int = Field(foreign_key="purchase_round.id", ondelete="CASCADE") order_number: int = Field() participant: "Participant" = Relationship(back_populates="orders") purchase_round: "PurchaseRound" = Relationship(back_populates="orders") order_lines: List["OrderLine"] = Relationship( back_populates="order", sa_relationship_kwargs={"cascade": "all, delete-orphan"} ) class OrderPublic(OrderBase): id: int participant_id: int purchase_round_id: int order_number: int class OrderConfirmation(OrderPublic): order_lines: List[OrderLinePublic]