from datetime import datetime from uuid import UUID as PyUUID from fastapi import FastAPI from sqlalchemy import ( String, Text, Boolean, Float, ForeignKey, TIMESTAMP, Integer, ) from sqlalchemy.dialects.postgresql import UUID as PG_UUID from sqlalchemy.ext.asyncio import create_async_engine from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy.sql import func from sqlalchemy.sql.expression import text\ class PaymentsBase(DeclarativeBase): pass class Deal(PaymentsBase): __tablename__ = "deals" id: Mapped[int] = mapped_column(primary_key=True) streamer_id: Mapped[int] = mapped_column() deal_id: Mapped[str] = mapped_column(Text, unique=True) amount: Mapped[int] = mapped_column(server_default=text("0")) open_status: Mapped[bool] = mapped_column(server_default=text("true")) created_at: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( TIMESTAMP(timezone=True), server_default=func.now(), onupdate=func.now() ) payments: Mapped[list["Payment"]] = relationship(back_populates="deal") def __str__(self): return f"Deal {self.deal_id}" class Balance(PaymentsBase): __tablename__ = "balances" id: Mapped[PyUUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, server_default=text("uuid_generate_v4()")) operation_type: Mapped[str] = mapped_column(String(20)) balance_diff: Mapped[int] = mapped_column() balance_total: Mapped[int] = mapped_column() streamer_id: Mapped[int] = mapped_column() created_at: Mapped[datetime] = mapped_column(TIMESTAMP, server_default=func.now()) def __str__(self): return f"Balance {self.id}" class Payment(PaymentsBase): __tablename__ = "payments" order_id: Mapped[PyUUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True) deal_id: Mapped[str] = mapped_column(ForeignKey("deals.deal_id", ondelete="CASCADE")) balance_id: Mapped[PyUUID | None] = mapped_column(ForeignKey("balances.id")) streamer_id: Mapped[int] = mapped_column() amount: Mapped[int] = mapped_column() created_at: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( TIMESTAMP(timezone=True), server_default=func.now(), onupdate=func.now() ) deal: Mapped["Deal"] = relationship(back_populates="payments") balance: Mapped["Balance"] = relationship() def __str__(self): return f"Payment {self.order_id}" class TinkoffWithdrawMethod(PaymentsBase): __tablename__ = "tinkoff_withdraw_methods" id: Mapped[PyUUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True, server_default=text("uuid_generate_v4()")) bank_name: Mapped[str] = mapped_column(String(100)) card_id: Mapped[str | None] = mapped_column(String(100)) sbp_member_id: Mapped[str | None] = mapped_column(String(100)) type: Mapped[str] = mapped_column(String(20)) streamer_id: Mapped[int] = mapped_column() phone: Mapped[str | None] = mapped_column(String(30)) card_pan: Mapped[str | None] = mapped_column(String(20)) request_id: Mapped[PyUUID | None] = mapped_column(PG_UUID(as_uuid=True)) is_main: Mapped[bool] = mapped_column(server_default=text("true")) created_at: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), server_default=func.now()) removed_at: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True)) def __str__(self): return f"Method {self.id} ({self.type})" class TinkoffWithdraw(PaymentsBase): __tablename__ = "tinkoff_withdraws" order_id: Mapped[PyUUID] = mapped_column(PG_UUID(as_uuid=True), primary_key=True) streamer_id: Mapped[int] = mapped_column() status: Mapped[str] = mapped_column(String(20)) payment_id: Mapped[str] = mapped_column(String(100)) amount: Mapped[int] = mapped_column() created_at: Mapped[datetime] = mapped_column(TIMESTAMP, server_default=func.now()) balance_id: Mapped[PyUUID | None] = mapped_column(ForeignKey("balances.id")) tinkoff_withdraw_method_id: Mapped[PyUUID] = mapped_column(ForeignKey("tinkoff_withdraw_methods.id")) balance: Mapped["Balance"] = relationship() tinkoff_withdraw_method: Mapped["TinkoffWithdrawMethod"] = relationship() def __str__(self): return f"Withdraw {self.order_id}" class StreamersCommission(PaymentsBase): __tablename__ = "streamers_commissions" streamer_id: Mapped[int] = mapped_column(primary_key=True) withdraw_comission_sbp: Mapped[int] = mapped_column() withdraw_comission_card: Mapped[int] = mapped_column() def __str__(self): return f"Commission for {self.streamer_id}"