Edit on GitHub

src.db.models.transactions

  1from collections.abc import Iterable
  2from datetime import datetime
  3from uuid import UUID
  4
  5from fastui.components.display import DisplayLookup, DisplayMode
  6from fastui.events import GoToEvent
  7from pydantic import (BaseModel, ConfigDict, Field, field_validator,
  8                      model_validator)
  9from sqlalchemy import BigInteger, DateTime, ForeignKey
 10from sqlalchemy.orm import Mapped, mapped_column, relationship
 11
 12from core.config import Base
 13
 14
 15class Transactions(Base):
 16    """Модель транзакций.
 17
 18    Эта модель представляет собой структуру данных для хранения информации
 19    о транзакциях пользователей.
 20    """
 21
 22    __tablename__ = "transactions"
 23    __table_args__ = {"extend_existing": True}
 24
 25    id: Mapped[int] = mapped_column(primary_key=True)
 26    """int: Уникальный идентификатор транзакции."""
 27
 28    user_id: Mapped[int] = mapped_column(
 29        ForeignKey("userdata.telegram_id", ondelete="CASCADE"), type_=BigInteger
 30    )
 31    """int: Идентификатор пользователя в Telegram, связанный с транзакцией."""
 32
 33    date: Mapped[datetime] = mapped_column(type_=DateTime(timezone=True))
 34    """datetime: Дата и время транзакции с учетом часового пояса."""
 35
 36    amount: Mapped[float]
 37    """float: Сумма транзакции."""
 38
 39    label: Mapped[UUID]
 40    """UUID: Метка транзакции."""
 41
 42    # PAYED
 43    transaction_id: Mapped[str | None]
 44    """str | None: Идентификатор транзакции (по умолчанию None)."""
 45
 46    sha1_hash: Mapped[str | None]
 47    """str | None: SHA-1 хэш транзакции (по умолчанию None)."""
 48
 49    sender: Mapped[str | None]
 50    """str | None: Отправитель транзакции (по умолчанию None)."""
 51
 52    withdraw_amount: Mapped[float | None]
 53    """float | None: Сумма вывода (по умолчанию None)."""
 54
 55    # additionally
 56    transaction_reference: Mapped[str]
 57    """str: Ссылка на транзакцию."""
 58
 59    transact_connect: Mapped["UserData"] = relationship(  # noqa: F821 # type: ignore
 60        back_populates="transactions", lazy="subquery"
 61    )
 62    """UserData: Связанные транзакции пользователя"""
 63
 64    class ValidationSchema(BaseModel):
 65        """Схема валидации для модели транзакций.
 66
 67        Эта схема используется для валидации данных, связанных с транзакциями.
 68        """
 69
 70        id: int | None = Field(default=None, title="ID")
 71        """Уникальный идентификатор транзакции."""
 72
 73        user_id: int | None = Field(default=None, title="Telegram ID")
 74        """Идентификатор пользователя в Telegram (по умолчанию None)."""
 75
 76        date: datetime = Field(title="Transaction date")
 77        """Дата и время транзакции."""
 78
 79        amount: float = Field(title="Amount")
 80        """Сумма транзакции."""
 81
 82        label: UUID = Field(title="Label")
 83        """Метка транзакции."""
 84
 85        transaction_id: str | None = Field(default=None, title="Transaction ID")
 86        """Идентификатор транзакции (по умолчанию None)."""
 87
 88        sha1_hash: str | None = Field(default=None, title="Hash")
 89        """SHA-1 хэш транзакции (по умолчанию None)."""
 90
 91        sender: str | None = Field(default=None, title="Sender")
 92        """Отправитель транзакции (по умолчанию None)."""
 93
 94        withdraw_amount: float | None = Field(default=None, title="Withdraw_amount")
 95        """Сумма вывода (по умолчанию None)."""
 96
 97        transaction_reference: str | None = Field(
 98            default=None, title="Transaction Reference"
 99        )
100        """Ссылка на транзакцию (по умолчанию None)."""
101
102        site_date: str = Field(init=False, title="Transaction date", default="00:00")
103        """Строковое представление даты транзакции (не инициализируется при создании)."""
104
105        @field_validator("amount", "withdraw_amount")
106        def round_amount(cls, v):
107            """Сумма транзакции (округленная)."""
108            return round(v, 2)
109
110        @model_validator(mode="before")
111        def convert_str_to_none(cls, values):
112            """Преобразует строки 'None' в None.
113
114            Args:
115                cls: Класс схемы.
116                values: Значения для валидации.
117
118            Returns:
119                dict: Обновленные значения.
120            """
121            if isinstance(values, Iterable):
122                return {k: None if v == "None" else v for k, v in dict(values).items()}
123            return values
124
125        @model_validator(mode="after")
126        def set_site_date(cls, values: BaseModel):
127            """Устанавливает строковое представление даты транзакции.
128
129            Args:
130                cls: Класс схемы.
131                values (BaseModel): Значения для валидации.
132
133            Returns:
134                BaseModel: Обновленные значения.
135            """
136            if hasattr(values, "date"):
137                values.site_date = values.date.astimezone().ctime()
138            return values
139
140        model_config = ConfigDict(extra="ignore")
141
142    # INTERFACE (fastui)
143    site_display = [
144        DisplayLookup(field="id"),
145        DisplayLookup(
146            field="user_id",
147            mode=DisplayMode.plain,
148            on_click=GoToEvent(url="/bot/tables/userdata/?telegram_id={user_id}"),
149        ),
150        DisplayLookup(field="site_date"),
151        DisplayLookup(field="amount"),
152        DisplayLookup(
153            field="label",
154            on_click=GoToEvent(url="/bot/tables/transactions/?label={label}"),
155        ),
156    ]
157    """list[DisplayLookup]: Отображение транзакций на сайте."""
158
159    site_display_all = site_display + [
160        DisplayLookup(field="sender"),
161        DisplayLookup(field="transaction_id", mode=DisplayMode.plain),
162        DisplayLookup(field="sha1_hash", mode=DisplayMode.inline_code),
163        DisplayLookup(field="withdraw_amount"),
164    ]
165    """list[DisplayLookup]: Полное отображение транзакций на сайте."""
166
167    def __init__(self, **kwargs):
168        """Инициализирует модель транзакций.
169
170        Args:
171            **kwargs: Дополнительные параметры для инициализации модели.
172        """
173        if kwargs:
174            validated_data = self.ValidationSchema(**kwargs).model_dump(
175                exclude={"site_date"}
176            )
177            super().__init__(**(validated_data))
178        else:
179            super().__init__(**(kwargs))
class Transactions(sqlalchemy.inspection.Inspectable[sqlalchemy.orm.state.InstanceState[typing.Any]]):
 16class Transactions(Base):
 17    """Модель транзакций.
 18
 19    Эта модель представляет собой структуру данных для хранения информации
 20    о транзакциях пользователей.
 21    """
 22
 23    __tablename__ = "transactions"
 24    __table_args__ = {"extend_existing": True}
 25
 26    id: Mapped[int] = mapped_column(primary_key=True)
 27    """int: Уникальный идентификатор транзакции."""
 28
 29    user_id: Mapped[int] = mapped_column(
 30        ForeignKey("userdata.telegram_id", ondelete="CASCADE"), type_=BigInteger
 31    )
 32    """int: Идентификатор пользователя в Telegram, связанный с транзакцией."""
 33
 34    date: Mapped[datetime] = mapped_column(type_=DateTime(timezone=True))
 35    """datetime: Дата и время транзакции с учетом часового пояса."""
 36
 37    amount: Mapped[float]
 38    """float: Сумма транзакции."""
 39
 40    label: Mapped[UUID]
 41    """UUID: Метка транзакции."""
 42
 43    # PAYED
 44    transaction_id: Mapped[str | None]
 45    """str | None: Идентификатор транзакции (по умолчанию None)."""
 46
 47    sha1_hash: Mapped[str | None]
 48    """str | None: SHA-1 хэш транзакции (по умолчанию None)."""
 49
 50    sender: Mapped[str | None]
 51    """str | None: Отправитель транзакции (по умолчанию None)."""
 52
 53    withdraw_amount: Mapped[float | None]
 54    """float | None: Сумма вывода (по умолчанию None)."""
 55
 56    # additionally
 57    transaction_reference: Mapped[str]
 58    """str: Ссылка на транзакцию."""
 59
 60    transact_connect: Mapped["UserData"] = relationship(  # noqa: F821 # type: ignore
 61        back_populates="transactions", lazy="subquery"
 62    )
 63    """UserData: Связанные транзакции пользователя"""
 64
 65    class ValidationSchema(BaseModel):
 66        """Схема валидации для модели транзакций.
 67
 68        Эта схема используется для валидации данных, связанных с транзакциями.
 69        """
 70
 71        id: int | None = Field(default=None, title="ID")
 72        """Уникальный идентификатор транзакции."""
 73
 74        user_id: int | None = Field(default=None, title="Telegram ID")
 75        """Идентификатор пользователя в Telegram (по умолчанию None)."""
 76
 77        date: datetime = Field(title="Transaction date")
 78        """Дата и время транзакции."""
 79
 80        amount: float = Field(title="Amount")
 81        """Сумма транзакции."""
 82
 83        label: UUID = Field(title="Label")
 84        """Метка транзакции."""
 85
 86        transaction_id: str | None = Field(default=None, title="Transaction ID")
 87        """Идентификатор транзакции (по умолчанию None)."""
 88
 89        sha1_hash: str | None = Field(default=None, title="Hash")
 90        """SHA-1 хэш транзакции (по умолчанию None)."""
 91
 92        sender: str | None = Field(default=None, title="Sender")
 93        """Отправитель транзакции (по умолчанию None)."""
 94
 95        withdraw_amount: float | None = Field(default=None, title="Withdraw_amount")
 96        """Сумма вывода (по умолчанию None)."""
 97
 98        transaction_reference: str | None = Field(
 99            default=None, title="Transaction Reference"
100        )
101        """Ссылка на транзакцию (по умолчанию None)."""
102
103        site_date: str = Field(init=False, title="Transaction date", default="00:00")
104        """Строковое представление даты транзакции (не инициализируется при создании)."""
105
106        @field_validator("amount", "withdraw_amount")
107        def round_amount(cls, v):
108            """Сумма транзакции (округленная)."""
109            return round(v, 2)
110
111        @model_validator(mode="before")
112        def convert_str_to_none(cls, values):
113            """Преобразует строки 'None' в None.
114
115            Args:
116                cls: Класс схемы.
117                values: Значения для валидации.
118
119            Returns:
120                dict: Обновленные значения.
121            """
122            if isinstance(values, Iterable):
123                return {k: None if v == "None" else v for k, v in dict(values).items()}
124            return values
125
126        @model_validator(mode="after")
127        def set_site_date(cls, values: BaseModel):
128            """Устанавливает строковое представление даты транзакции.
129
130            Args:
131                cls: Класс схемы.
132                values (BaseModel): Значения для валидации.
133
134            Returns:
135                BaseModel: Обновленные значения.
136            """
137            if hasattr(values, "date"):
138                values.site_date = values.date.astimezone().ctime()
139            return values
140
141        model_config = ConfigDict(extra="ignore")
142
143    # INTERFACE (fastui)
144    site_display = [
145        DisplayLookup(field="id"),
146        DisplayLookup(
147            field="user_id",
148            mode=DisplayMode.plain,
149            on_click=GoToEvent(url="/bot/tables/userdata/?telegram_id={user_id}"),
150        ),
151        DisplayLookup(field="site_date"),
152        DisplayLookup(field="amount"),
153        DisplayLookup(
154            field="label",
155            on_click=GoToEvent(url="/bot/tables/transactions/?label={label}"),
156        ),
157    ]
158    """list[DisplayLookup]: Отображение транзакций на сайте."""
159
160    site_display_all = site_display + [
161        DisplayLookup(field="sender"),
162        DisplayLookup(field="transaction_id", mode=DisplayMode.plain),
163        DisplayLookup(field="sha1_hash", mode=DisplayMode.inline_code),
164        DisplayLookup(field="withdraw_amount"),
165    ]
166    """list[DisplayLookup]: Полное отображение транзакций на сайте."""
167
168    def __init__(self, **kwargs):
169        """Инициализирует модель транзакций.
170
171        Args:
172            **kwargs: Дополнительные параметры для инициализации модели.
173        """
174        if kwargs:
175            validated_data = self.ValidationSchema(**kwargs).model_dump(
176                exclude={"site_date"}
177            )
178            super().__init__(**(validated_data))
179        else:
180            super().__init__(**(kwargs))

Модель транзакций.

Эта модель представляет собой структуру данных для хранения информации о транзакциях пользователей.

Transactions(**kwargs)

Инициализирует модель транзакций.

Arguments:
  • **kwargs: Дополнительные параметры для инициализации модели.
id: sqlalchemy.orm.base.Mapped[int]

int: Уникальный идентификатор транзакции.

user_id: sqlalchemy.orm.base.Mapped[int]

int: Идентификатор пользователя в Telegram, связанный с транзакцией.

date: sqlalchemy.orm.base.Mapped[datetime.datetime]

datetime: Дата и время транзакции с учетом часового пояса.

amount: sqlalchemy.orm.base.Mapped[float]

float: Сумма транзакции.

label: sqlalchemy.orm.base.Mapped[uuid.UUID]

UUID: Метка транзакции.

transaction_id: sqlalchemy.orm.base.Mapped[str | None]

str | None: Идентификатор транзакции (по умолчанию None).

sha1_hash: sqlalchemy.orm.base.Mapped[str | None]

str | None: SHA-1 хэш транзакции (по умолчанию None).

sender: sqlalchemy.orm.base.Mapped[str | None]

str | None: Отправитель транзакции (по умолчанию None).

withdraw_amount: sqlalchemy.orm.base.Mapped[float | None]

float | None: Сумма вывода (по умолчанию None).

transaction_reference: sqlalchemy.orm.base.Mapped[str]

str: Ссылка на транзакцию.

transact_connect: sqlalchemy.orm.base.Mapped[ForwardRef('UserData')]

UserData: Связанные транзакции пользователя

site_display = [DisplayLookup(mode=None, title=None, on_click=None, field='id', table_width_percent=None), DisplayLookup(mode=<DisplayMode.plain: 'plain'>, title=None, on_click=GoToEvent(url='/bot/tables/userdata/?telegram_id={user_id}', query=None, target=None, type='go-to'), field='user_id', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='site_date', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='amount', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=GoToEvent(url='/bot/tables/transactions/?label={label}', query=None, target=None, type='go-to'), field='label', table_width_percent=None)]

list[DisplayLookup]: Отображение транзакций на сайте.

site_display_all = [DisplayLookup(mode=None, title=None, on_click=None, field='id', table_width_percent=None), DisplayLookup(mode=<DisplayMode.plain: 'plain'>, title=None, on_click=GoToEvent(url='/bot/tables/userdata/?telegram_id={user_id}', query=None, target=None, type='go-to'), field='user_id', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='site_date', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='amount', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=GoToEvent(url='/bot/tables/transactions/?label={label}', query=None, target=None, type='go-to'), field='label', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='sender', table_width_percent=None), DisplayLookup(mode=<DisplayMode.plain: 'plain'>, title=None, on_click=None, field='transaction_id', table_width_percent=None), DisplayLookup(mode=<DisplayMode.inline_code: 'inline_code'>, title=None, on_click=None, field='sha1_hash', table_width_percent=None), DisplayLookup(mode=None, title=None, on_click=None, field='withdraw_amount', table_width_percent=None)]

list[DisplayLookup]: Полное отображение транзакций на сайте.

class Transactions.ValidationSchema(pydantic.main.BaseModel):
 65    class ValidationSchema(BaseModel):
 66        """Схема валидации для модели транзакций.
 67
 68        Эта схема используется для валидации данных, связанных с транзакциями.
 69        """
 70
 71        id: int | None = Field(default=None, title="ID")
 72        """Уникальный идентификатор транзакции."""
 73
 74        user_id: int | None = Field(default=None, title="Telegram ID")
 75        """Идентификатор пользователя в Telegram (по умолчанию None)."""
 76
 77        date: datetime = Field(title="Transaction date")
 78        """Дата и время транзакции."""
 79
 80        amount: float = Field(title="Amount")
 81        """Сумма транзакции."""
 82
 83        label: UUID = Field(title="Label")
 84        """Метка транзакции."""
 85
 86        transaction_id: str | None = Field(default=None, title="Transaction ID")
 87        """Идентификатор транзакции (по умолчанию None)."""
 88
 89        sha1_hash: str | None = Field(default=None, title="Hash")
 90        """SHA-1 хэш транзакции (по умолчанию None)."""
 91
 92        sender: str | None = Field(default=None, title="Sender")
 93        """Отправитель транзакции (по умолчанию None)."""
 94
 95        withdraw_amount: float | None = Field(default=None, title="Withdraw_amount")
 96        """Сумма вывода (по умолчанию None)."""
 97
 98        transaction_reference: str | None = Field(
 99            default=None, title="Transaction Reference"
100        )
101        """Ссылка на транзакцию (по умолчанию None)."""
102
103        site_date: str = Field(init=False, title="Transaction date", default="00:00")
104        """Строковое представление даты транзакции (не инициализируется при создании)."""
105
106        @field_validator("amount", "withdraw_amount")
107        def round_amount(cls, v):
108            """Сумма транзакции (округленная)."""
109            return round(v, 2)
110
111        @model_validator(mode="before")
112        def convert_str_to_none(cls, values):
113            """Преобразует строки 'None' в None.
114
115            Args:
116                cls: Класс схемы.
117                values: Значения для валидации.
118
119            Returns:
120                dict: Обновленные значения.
121            """
122            if isinstance(values, Iterable):
123                return {k: None if v == "None" else v for k, v in dict(values).items()}
124            return values
125
126        @model_validator(mode="after")
127        def set_site_date(cls, values: BaseModel):
128            """Устанавливает строковое представление даты транзакции.
129
130            Args:
131                cls: Класс схемы.
132                values (BaseModel): Значения для валидации.
133
134            Returns:
135                BaseModel: Обновленные значения.
136            """
137            if hasattr(values, "date"):
138                values.site_date = values.date.astimezone().ctime()
139            return values
140
141        model_config = ConfigDict(extra="ignore")

Схема валидации для модели транзакций.

Эта схема используется для валидации данных, связанных с транзакциями.

id: int | None

Уникальный идентификатор транзакции.

user_id: int | None

Идентификатор пользователя в Telegram (по умолчанию None).

date: datetime.datetime

Дата и время транзакции.

amount: float

Сумма транзакции.

label: uuid.UUID

Метка транзакции.

transaction_id: str | None

Идентификатор транзакции (по умолчанию None).

sha1_hash: str | None

SHA-1 хэш транзакции (по умолчанию None).

sender: str | None

Отправитель транзакции (по умолчанию None).

withdraw_amount: float | None

Сумма вывода (по умолчанию None).

transaction_reference: str | None

Ссылка на транзакцию (по умолчанию None).

site_date: str

Строковое представление даты транзакции (не инициализируется при создании).

@field_validator('amount', 'withdraw_amount')
def round_amount(cls, v):
106        @field_validator("amount", "withdraw_amount")
107        def round_amount(cls, v):
108            """Сумма транзакции (округленная)."""
109            return round(v, 2)

Сумма транзакции (округленная).

@model_validator(mode='before')
def convert_str_to_none(cls, values):
111        @model_validator(mode="before")
112        def convert_str_to_none(cls, values):
113            """Преобразует строки 'None' в None.
114
115            Args:
116                cls: Класс схемы.
117                values: Значения для валидации.
118
119            Returns:
120                dict: Обновленные значения.
121            """
122            if isinstance(values, Iterable):
123                return {k: None if v == "None" else v for k, v in dict(values).items()}
124            return values

Преобразует строки 'None' в None.

Arguments:
  • cls: Класс схемы.
  • values: Значения для валидации.
Returns:

dict: Обновленные значения.

@model_validator(mode='after')
def set_site_date(cls, values: pydantic.main.BaseModel):
126        @model_validator(mode="after")
127        def set_site_date(cls, values: BaseModel):
128            """Устанавливает строковое представление даты транзакции.
129
130            Args:
131                cls: Класс схемы.
132                values (BaseModel): Значения для валидации.
133
134            Returns:
135                BaseModel: Обновленные значения.
136            """
137            if hasattr(values, "date"):
138                values.site_date = values.date.astimezone().ctime()
139            return values

Устанавливает строковое представление даты транзакции.

Arguments:
  • cls: Класс схемы.
  • values (BaseModel): Значения для валидации.
Returns:

BaseModel: Обновленные значения.

model_config = {'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[Dict[str, pydantic.fields.FieldInfo]] = {'id': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, title='ID'), 'user_id': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, title='Telegram ID'), 'date': FieldInfo(annotation=datetime, required=True, title='Transaction date'), 'amount': FieldInfo(annotation=float, required=True, title='Amount'), 'label': FieldInfo(annotation=UUID, required=True, title='Label'), 'transaction_id': FieldInfo(annotation=Union[str, NoneType], required=False, default=None, title='Transaction ID'), 'sha1_hash': FieldInfo(annotation=Union[str, NoneType], required=False, default=None, title='Hash'), 'sender': FieldInfo(annotation=Union[str, NoneType], required=False, default=None, title='Sender'), 'withdraw_amount': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, title='Withdraw_amount'), 'transaction_reference': FieldInfo(annotation=Union[str, NoneType], required=False, default=None, title='Transaction Reference'), 'site_date': FieldInfo(annotation=str, required=False, default='00:00', title='Transaction date', init=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo] objects.

This replaces Model.__fields__ from Pydantic V1.

model_computed_fields: ClassVar[Dict[str, pydantic.fields.ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.