import datetime from enum import StrEnum from typing import Optional from sqlmodel import Column, Field, LargeBinary, Relationship, SQLModel class ContractType(SQLModel, table=True): id: int | None = Field( default=None, primary_key=True ) name: str class UserContractTypeLink(SQLModel, table=True): user_id: int = Field( foreign_key='user.id', primary_key=True ) contract_type_id: int = Field( foreign_key='contracttype.id', primary_key=True ) class UserBase(SQLModel): name: str email: str class UserPublic(UserBase): id: int roles: list[ContractType] class User(UserBase, table=True): id: int | None = Field(default=None, primary_key=True) roles: list[ContractType] = Relationship( link_model=UserContractTypeLink ) class UserUpdate(SQLModel): name: str | None email: str | None role_names: list[str] | None class UserCreate(UserBase): role_names: list[str] | None class PaymentMethodBase(SQLModel): name: str details: str max: int | None class PaymentMethod(PaymentMethodBase, table=True): id: int | None = Field(default=None, primary_key=True) productor_id: int = Field(foreign_key='productor.id', ondelete='CASCADE') productor: Optional['Productor'] = Relationship( back_populates='payment_methods', ) class PaymentMethodPublic(PaymentMethodBase): id: int productor: Optional['Productor'] class ProductorBase(SQLModel): name: str address: str type: str class ProductorPublic(ProductorBase): id: int products: list['Product'] = Field(default_factory=list) payment_methods: list['PaymentMethod'] = Field(default_factory=list) class Productor(ProductorBase, table=True): id: int | None = Field(default=None, primary_key=True) products: list['Product'] = Relationship( back_populates='productor', sa_relationship_kwargs={ 'order_by': 'Product.name' }, ) payment_methods: list['PaymentMethod'] = Relationship( back_populates='productor', cascade_delete=True ) class ProductorUpdate(SQLModel): name: str | None address: str | None payment_methods: list['PaymentMethod'] = Field(default_factory=list) type: str | None class ProductorCreate(ProductorBase): payment_methods: list['PaymentMethod'] = Field(default_factory=list) class Unit(StrEnum): GRAMS = '1' KILO = '2' PIECE = '3' class ProductType(StrEnum): OCCASIONAL = '1' RECCURENT = '2' class ShipmentProductLink(SQLModel, table=True): shipment_id: Optional[int] = Field( default=None, foreign_key='shipment.id', primary_key=True ) product_id: Optional[int] = Field( default=None, foreign_key='product.id', primary_key=True ) class ProductBase(SQLModel): name: str unit: Unit price: float | None price_kg: float | None quantity: float | None quantity_unit: str | None type: ProductType productor_id: int | None = Field( default=None, foreign_key='productor.id' ) class ProductPublic(ProductBase): id: int productor: Productor | None shipments: list['Shipment'] | None class Product(ProductBase, table=True): id: int | None = Field( default=None, primary_key=True ) shipments: list['Shipment'] = Relationship( back_populates='products', link_model=ShipmentProductLink ) productor: Optional[Productor] = Relationship( back_populates='products' ) class ProductUpdate(SQLModel): name: str | None unit: Unit | None price: float | None price_kg: float | None quantity: float | None quantity_unit: str | None productor_id: int | None type: ProductType | None class ProductCreate(ProductBase): pass class FormBase(SQLModel): name: str productor_id: int | None = Field(default=None, foreign_key='productor.id') referer_id: int | None = Field(default=None, foreign_key='user.id') season: str start: datetime.date end: datetime.date minimum_shipment_value: float | None visible: bool class FormPublic(FormBase): id: int productor: ProductorPublic | None referer: User | None shipments: list['ShipmentPublic'] = Field(default_factory=list) class Form(FormBase, table=True): id: int | None = Field(default=None, primary_key=True) productor: Optional['Productor'] = Relationship() referer: Optional['User'] = Relationship() shipments: list['Shipment'] = Relationship( back_populates='form', cascade_delete=True, sa_relationship_kwargs={ 'order_by': 'Shipment.name' }, ) contracts: list['Contract'] = Relationship( back_populates='form', cascade_delete=True ) class FormUpdate(SQLModel): name: str | None productor_id: int | None referer_id: int | None season: str | None start: datetime.date | None end: datetime.date | None minimum_shipment_value: float | None visible: bool | None class FormCreate(FormBase): pass class TemplateBase(SQLModel): pass class TemplatePublic(TemplateBase): id: int class Template(TemplateBase, table=True): id: int | None = Field(default=None, primary_key=True) class TemplateUpdate(SQLModel): pass class TemplateCreate(TemplateBase): pass class ChequeBase(SQLModel): name: str value: str class Cheque(ChequeBase, table=True): id: int | None = Field(default=None, primary_key=True) contract_id: int = Field(foreign_key='contract.id', ondelete='CASCADE') contract: Optional['Contract'] = Relationship( back_populates='cheques', ) class ContractBase(SQLModel): firstname: str lastname: str email: str phone: str payment_method: str cheque_quantity: int class Contract(ContractBase, table=True): id: int | None = Field(default=None, primary_key=True) form_id: int = Field( foreign_key='form.id', nullable=False, ondelete='CASCADE' ) products: list['ContractProduct'] = Relationship( back_populates='contract', cascade_delete=True ) form: Form = Relationship(back_populates='contracts') cheques: list[Cheque] = Relationship( back_populates='contract', cascade_delete=True ) file: bytes = Field(sa_column=Column(LargeBinary)) total_price: float | None class ContractCreate(ContractBase): products: list['ContractProductCreate'] = Field(default_factory=list) cheques: list['Cheque'] = Field(default_factory=list) form_id: int class ContractUpdate(SQLModel): file: bytes class ContractPublic(ContractBase): id: int products: list['ContractProduct'] = Field(default_factory=list) form: Form total_price: float | None # file: bytes class ContractProductBase(SQLModel): product_id: int = Field( foreign_key='product.id', nullable=False, ondelete='CASCADE' ) shipment_id: int | None = Field( default=None, foreign_key='shipment.id', nullable=True, ondelete='CASCADE' ) quantity: float class ContractProduct(ContractProductBase, table=True): id: int | None = Field(default=None, primary_key=True) contract_id: int = Field( foreign_key='contract.id', nullable=False, ondelete='CASCADE' ) contract: Optional['Contract'] = Relationship(back_populates='products') product: Optional['Product'] = Relationship() shipment: Optional['Shipment'] = Relationship() class ContractProductPublic(ContractProductBase): id: int quantity: float contract: Contract product: Product shipment: Optional['Shipment'] class ContractProductCreate(ContractProductBase): pass class ContractProductUpdate(ContractProductBase): pass class ShipmentBase(SQLModel): name: str date: datetime.date form_id: int | None = Field( default=None, foreign_key='form.id', ondelete='CASCADE') class ShipmentPublic(ShipmentBase): id: int products: list[Product] = Field(default_factory=list) form: Form | None class Shipment(ShipmentBase, table=True): id: int | None = Field(default=None, primary_key=True) products: list[Product] = Relationship( back_populates='shipments', link_model=ShipmentProductLink, sa_relationship_kwargs={ 'order_by': 'Product.name' }, ) form: Optional[Form] = Relationship(back_populates='shipments') class ShipmentUpdate(SQLModel): name: str | None date: datetime.date | None product_ids: list[int] | None = Field(default_factory=list) class ShipmentCreate(ShipmentBase): product_ids: list[int] = Field(default_factory=list) form_id: int