from datetime import datetime from enum import IntEnum, unique from typing import Optional, TYPE_CHECKING from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Boolean from sqlalchemy.orm import relationship, backref, Mapped, mapped_column from models.base import BaseModel from .marketplace import BaseMarketplace from .shipping_warehouse import ShippingWarehouse if TYPE_CHECKING: from . import (DealBillRequest, ServicePriceCategory, # DealGroup ) # @unique # class DealStatus(IntEnum): # CREATED = 0 # AWAITING_ACCEPTANCE = 1 # PACKAGING = 2 # AWAITING_SHIPMENT = 3 # AWAITING_PAYMENT = 4 # COMPLETED = 5 # CANCELLED = 6 @unique class DealStatus(IntEnum): CREATED = 0 AWAITING_ACCEPTANCE = 1 READY_FOR_WORK = 2 PACKAGING = 3 AWAITING_SHIPMENT = 4 IN_DELIVERY = 5 AWAITING_PAYMENT = 6 COMPLETED = 7 CANCELLED = 8 class DealPriceCategory(BaseModel): __tablename__ = 'deal_price_category' deal_id: Mapped[int] = mapped_column(ForeignKey('deals.id'), primary_key=True, unique=True) category_id: Mapped[int] = mapped_column(ForeignKey('service_price_category.id'), primary_key=True) class Deal(BaseModel): __tablename__ = 'deals' id = Column(Integer, autoincrement=True, primary_key=True, index=True) name = Column(String, nullable=False, comment='Название сделки') created_at = Column(DateTime, nullable=False, comment='Дата создания') current_status = Column(Integer, nullable=False, comment='Текущий статус') client_id = Column(Integer, ForeignKey('clients.id', ondelete='CASCADE'), nullable=False, comment='ID клиента') client = relationship('Client', backref=backref('deals', cascade="all, delete-orphan")) status_history = relationship('DealStatusHistory', back_populates='deal', cascade="all, delete-orphan") is_deleted = Column(Boolean, nullable=False, server_default='0', default=False, comment='Удалена') is_completed = Column(Boolean, nullable=False, server_default='0', default=False, comment='Завершена') 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") delivery_date: Mapped[Optional[datetime]] = mapped_column(nullable=True) receiving_slot_date: Mapped[Optional[datetime]] = mapped_column(nullable=True) services = relationship( 'DealService', back_populates='deal', cascade="all, delete-orphan", order_by="desc(DealService.service_id)" ) products = relationship( 'DealProduct', back_populates='deal', cascade="all, delete-orphan", order_by="desc(DealProduct.product_id)" ) # TODO remake with sequence lexorank = Column(String, nullable=False, comment='Lexorank', index=True) comment = Column(String, nullable=False, server_default='', comment='Коментарий к заданию') bill_request: Mapped[Optional['DealBillRequest']] = relationship(back_populates='deal', lazy='joined') category: Mapped[Optional["ServicePriceCategory"]] = relationship('ServicePriceCategory', secondary=DealPriceCategory.__table__, lazy='joined') # group: Mapped[Optional["DealGroup"]] = relationship( # 'DealGroup', # secondary='deal_relations', # lazy='joined', # uselist=False, # back_populates='deals' # ) class DealStatusHistory(BaseModel): __tablename__ = 'deals_status_history' id = Column(Integer, autoincrement=True, primary_key=True, index=True) deal_id = Column(Integer, ForeignKey('deals.id'), nullable=False, comment='ID сделки') deal = relationship('Deal', back_populates='status_history') user_id = Column(Integer, ForeignKey('users.id'), nullable=False) user = relationship('User') changed_at = Column(DateTime, nullable=False, comment='Дата и время когда произошла смена статуса') from_status = Column(Integer, nullable=False, comment='Предыдущий статус') to_status = Column(Integer, nullable=False, comment='Новый статус') next_status_deadline = Column(DateTime, comment='Дедлайн до которого сделку нужно перевести на следующий этап') comment = Column(String, nullable=False, comment='Коментарий', server_default='')