from datetime import datetime from typing import Optional, TYPE_CHECKING from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship, backref, Mapped, mapped_column from models.base import BaseModel from .marketplace import BaseMarketplace from .shipping import Pallet, Box from .shipping_warehouse import ShippingWarehouse if TYPE_CHECKING: from . import CardBillRequest, User, BaseModel, Board, CardStatus, CardGroup, CardAttribute, CardService as CardServiceModel, \ CardProduct, Client class Card(BaseModel): __tablename__ = 'cards' # region Base card attributes id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(nullable=False, comment='Название карточки') comment: Mapped[str] = mapped_column(nullable=False, server_default='', comment='Комментарий') created_at: Mapped[datetime] = mapped_column(nullable=False, comment='Дата создания') is_deleted: Mapped[bool] = mapped_column(nullable=False, server_default='0', default=False, comment='Удалена') is_completed: Mapped[bool] = mapped_column(nullable=False, server_default='0', default=False, comment='Завершена') lexorank: Mapped[str] = mapped_column(nullable=False, comment='Lexorank', index=True) board_id: Mapped[int] = mapped_column(ForeignKey('boards.id'), nullable=True, server_default='1') board: Mapped['Board'] = relationship( 'Board', back_populates='cards', ) current_status_id: Mapped[int] = mapped_column( ForeignKey('card_statuses.id'), nullable=False, comment='Текущий статус', ) status: Mapped['CardStatus'] = relationship(lazy='selectin') status_history = relationship('CardStatusHistory', back_populates='card', cascade="all, delete-orphan") attributes: Mapped[list['CardAttribute']] = relationship( 'CardAttribute', uselist=True, back_populates='card', lazy='selectin', ) group: Mapped[Optional["CardGroup"]] = relationship( 'CardGroup', secondary='card_relations', lazy='joined', back_populates='cards' ) # endregion # region Attributes handled by modules # module servicesAndProducts is_locked: Mapped[bool] = mapped_column(default=False, server_default='0') shipping_warehouse_id: Mapped[int] = mapped_column(ForeignKey('shipping_warehouses.id'), nullable=True) shipping_warehouse: Mapped["ShippingWarehouse"] = relationship() base_marketplace_key: Mapped[str] = mapped_column(ForeignKey("base_marketplaces.key"), nullable=True) base_marketplace: Mapped["BaseMarketplace"] = relationship(lazy="joined") services: Mapped[list['CardServiceModel']] = relationship( 'CardService', back_populates='card', cascade="all, delete-orphan", order_by="desc(CardService.service_id)" ) products: Mapped[list['CardProduct']] = relationship( 'CardProduct', back_populates='card', cascade="all, delete-orphan", order_by="desc(CardProduct.product_id)" ) bill_request: Mapped[Optional['CardBillRequest']] = relationship(back_populates='card', lazy='joined') # module client client_id: Mapped[int] = mapped_column( ForeignKey('clients.id', ondelete='CASCADE'), nullable=False, comment='ID клиента', ) client: Mapped['Client'] = relationship('Client', backref=backref('cards', cascade="all, delete-orphan")) # module managers manager_id: Mapped[int] = mapped_column(ForeignKey('users.id'), nullable=True) manager: Mapped[Optional["User"]] = relationship(back_populates='managed_cards', lazy='joined') # module shipment pallets: Mapped[list[Pallet]] = relationship(back_populates='card', lazy='selectin') boxes: Mapped[list[Box]] = relationship(back_populates='card', lazy='selectin') # module employees employees: Mapped[list['CardEmployees']] = relationship(back_populates='card', lazy='selectin') # endregion class CardEmployees(BaseModel): __tablename__ = 'card_employees' user_id: Mapped[int] = mapped_column(ForeignKey('users.id'), primary_key=True) user: Mapped['User'] = relationship('User', back_populates='cards', lazy='selectin') card_id: Mapped[int] = mapped_column(ForeignKey('cards.id'), primary_key=True) card: Mapped[Card] = relationship('Card', back_populates='employees', lazy='selectin') created_at: Mapped[datetime] = mapped_column()