diff --git a/app/database/models.py b/app/database/models.py
index b017a26c..e689b1da 100644
--- a/app/database/models.py
+++ b/app/database/models.py
@@ -224,18 +224,8 @@ class User(Base):
vless_uuid = Column(String(255), nullable=True)
ss_password = Column(String(255), nullable=True)
has_made_first_topup: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
- auto_assigned_promo_group_id = Column(
- Integer,
- ForeignKey("promo_groups.id", ondelete="SET NULL"),
- nullable=True,
- )
promo_group_id = Column(Integer, ForeignKey("promo_groups.id", ondelete="RESTRICT"), nullable=False, index=True)
promo_group = relationship("PromoGroup", back_populates="users")
- auto_assigned_promo_group = relationship(
- "PromoGroup",
- foreign_keys=[auto_assigned_promo_group_id],
- viewonly=True,
- )
@property
def balance_rubles(self) -> float:
diff --git a/app/database/universal_migration.py b/app/database/universal_migration.py
index e0a61a46..aa68e45f 100644
--- a/app/database/universal_migration.py
+++ b/app/database/universal_migration.py
@@ -532,31 +532,6 @@ async def ensure_promo_groups_setup():
except Exception as e:
logger.warning(f"Не удалось создать индекс ix_users_promo_group_id: {e}")
- auto_assigned_column_exists = await check_column_exists(
- "users", "auto_assigned_promo_group_id"
- )
-
- if not auto_assigned_column_exists:
- if db_type == "sqlite":
- await conn.execute(
- text("ALTER TABLE users ADD COLUMN auto_assigned_promo_group_id INTEGER")
- )
- elif db_type == "postgresql":
- await conn.execute(
- text("ALTER TABLE users ADD COLUMN auto_assigned_promo_group_id INTEGER")
- )
- elif db_type == "mysql":
- await conn.execute(
- text("ALTER TABLE users ADD COLUMN auto_assigned_promo_group_id INT")
- )
- else:
- logger.error(
- f"Неподдерживаемый тип БД для users.auto_assigned_promo_group_id: {db_type}"
- )
- return False
-
- logger.info("Добавлена колонка users.auto_assigned_promo_group_id")
-
default_group_name = "Базовый юзер"
default_group_id = None
@@ -1275,8 +1250,7 @@ async def check_migration_status():
"promo_groups_table": False,
"promo_groups_auto_assign_column": False,
"promo_groups_spent_threshold_column": False,
- "users_promo_group_column": False,
- "users_auto_assigned_promo_group_column": False,
+ "users_promo_group_column": False
}
status["has_made_first_topup_column"] = await check_column_exists('users', 'has_made_first_topup')
@@ -1295,9 +1269,6 @@ async def check_migration_status():
status["welcome_texts_is_enabled_column"] = await check_column_exists('welcome_texts', 'is_enabled')
status["users_promo_group_column"] = await check_column_exists('users', 'promo_group_id')
- status["users_auto_assigned_promo_group_column"] = await check_column_exists(
- 'users', 'auto_assigned_promo_group_id'
- )
media_fields_exist = (
await check_column_exists('broadcast_history', 'has_media') and
@@ -1331,8 +1302,7 @@ async def check_migration_status():
"promo_groups_table": "Таблица промо-групп",
"promo_groups_auto_assign_column": "Колонка auto_assign_enabled у промогрупп",
"promo_groups_spent_threshold_column": "Колонка spent_threshold_kopeks у промогрупп",
- "users_promo_group_column": "Колонка promo_group_id у пользователей",
- "users_auto_assigned_promo_group_column": "Колонка auto_assigned_promo_group_id у пользователей",
+ "users_promo_group_column": "Колонка promo_group_id у пользователей"
}
for check_key, check_status in status.items():
diff --git a/app/handlers/admin/promo_groups.py b/app/handlers/admin/promo_groups.py
index c89f77c1..3ef83a03 100644
--- a/app/handlers/admin/promo_groups.py
+++ b/app/handlers/admin/promo_groups.py
@@ -349,20 +349,8 @@ async def process_create_group_devices(
await message.answer(
texts.t(
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT",
- "Включить автоматическое назначение по сумме трат?",
- ),
- reply_markup=types.InlineKeyboardMarkup(
- inline_keyboard=[
- [
- types.InlineKeyboardButton(
- text=texts.YES, callback_data="promo_group_auto_assign_yes"
- ),
- types.InlineKeyboardButton(
- text=texts.NO, callback_data="promo_group_auto_assign_no"
- ),
- ]
- ]
- ),
+ "Включить автоматическое назначение по сумме трат? (да/нет)",
+ )
)
@@ -418,7 +406,7 @@ async def _finalize_create_group(
@admin_required
@error_handler
async def process_create_group_auto_assign_enabled(
- callback: types.CallbackQuery,
+ message: types.Message,
state: FSMContext,
db_user,
db: AsyncSession,
@@ -426,38 +414,32 @@ async def process_create_group_auto_assign_enabled(
data = await state.get_data()
texts = get_texts(data.get("language", db_user.language))
- if callback.data not in {
- "promo_group_auto_assign_yes",
- "promo_group_auto_assign_no",
- }:
- await callback.answer(texts.t("ADMIN_ACTION_INVALID", "Недопустимое действие"), show_alert=True)
+ try:
+ auto_enabled = _parse_bool_response(message.text)
+ except ValueError:
+ await message.answer(texts.t("ADMIN_PROMO_GROUP_INVALID_BOOL", "Введите «да» или «нет»."))
return
- auto_enabled = callback.data == "promo_group_auto_assign_yes"
await state.update_data(new_group_auto_assign_enabled=auto_enabled)
if auto_enabled:
await state.set_state(AdminStates.creating_promo_group_auto_assign_threshold)
- await callback.message.edit_text(
+ await message.answer(
texts.t(
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_THRESHOLD_PROMPT",
"Введите сумму трат в рублях для автоматического назначения:",
)
)
- await callback.answer()
return
- await callback.message.edit_reply_markup()
-
await _finalize_create_group(
- callback.message,
+ message,
state,
db_user,
db,
auto_assign_enabled=False,
spent_threshold_kopeks=0,
)
- await callback.answer()
@admin_required
@@ -872,10 +854,9 @@ def register_handlers(dp: Dispatcher):
process_create_group_devices,
AdminStates.creating_promo_group_device_discount,
)
- dp.callback_query.register(
+ dp.message.register(
process_create_group_auto_assign_enabled,
AdminStates.creating_promo_group_auto_assign_enabled,
- F.data.in_({"promo_group_auto_assign_yes", "promo_group_auto_assign_no"}),
)
dp.message.register(
process_create_group_auto_assign_threshold,
diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json
index 29abcb8b..c9f29fbc 100644
--- a/app/localization/locales/en.json
+++ b/app/localization/locales/en.json
@@ -114,7 +114,6 @@
"WELCOME": "\n🎉 Welcome to VPN Service!\n\nOur service provides fast and secure internet access without restrictions.\n\n🔐 Advantages:\n• High connection speed\n• Servers in different countries \n• Reliable data protection\n• 24/7 support\n\nTo get started, select interface language:\n",
"WELCOME_FALLBACK": "Welcome, {user_name}!",
"YES": "✅ Yes",
- "ADMIN_ACTION_INVALID": "Invalid action",
"ACCESS_DENIED": "❌ Access denied",
"ADMIN_MESSAGES": "📨 Broadcasts",
"ADMIN_MONITORING": "🔍 Monitoring",
@@ -155,7 +154,7 @@
"ADMIN_PROMO_GROUP_CREATE_TRAFFIC_PROMPT": "Enter traffic discount (0-100):",
"ADMIN_PROMO_GROUP_CREATE_SERVERS_PROMPT": "Enter server discount (0-100):",
"ADMIN_PROMO_GROUP_CREATE_DEVICES_PROMPT": "Enter device discount (0-100):",
- "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Enable automatic assignment by total spending?",
+ "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Enable automatic assignment by total spending? (yes/no)",
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_THRESHOLD_PROMPT": "Enter the spending amount in RUB required for automatic assignment:",
"ADMIN_PROMO_GROUP_INVALID_PERCENT": "Enter a number from 0 to 100.",
"ADMIN_PROMO_GROUP_INVALID_BOOL": "Please answer \"yes\" or \"no\".",
diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json
index a5d3f7ef..2d3a49ca 100644
--- a/app/localization/locales/ru.json
+++ b/app/localization/locales/ru.json
@@ -42,7 +42,7 @@
"ADMIN_PROMO_GROUP_CREATE_TRAFFIC_PROMPT": "Введите скидку на трафик (0-100):",
"ADMIN_PROMO_GROUP_CREATE_SERVERS_PROMPT": "Введите скидку на серверы (0-100):",
"ADMIN_PROMO_GROUP_CREATE_DEVICES_PROMPT": "Введите скидку на устройства (0-100):",
- "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Включить автоматическое назначение по сумме трат?",
+ "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Включить автоматическое назначение по сумме трат? (да/нет)",
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_THRESHOLD_PROMPT": "Введите сумму трат в рублях для автоматического назначения:",
"ADMIN_PROMO_GROUP_INVALID_PERCENT": "Введите число от 0 до 100.",
"ADMIN_PROMO_GROUP_INVALID_BOOL": "Введите «да» или «нет».",
@@ -288,7 +288,6 @@
"WELCOME": "\n🎉 Добро пожаловать в VPN сервис!\n\nНаш сервис предоставляет быстрый и безопасный доступ к интернету без ограничений.\n\n🔐 Преимущества:\n• Высокая скорость подключения\n• Серверы в разных странах\n• Надежная защита данных\n• Круглосуточная поддержка\n\nДля начала работы выберите язык интерфейса:\n",
"WELCOME_FALLBACK": "Добро пожаловать, {user_name}!",
"YES": "✅ Да",
- "ADMIN_ACTION_INVALID": "Недопустимое действие",
"SUBSCRIPTION_STATUS_EXPIRED": "Истекла",
"SUBSCRIPTION_STATUS_TRIAL": "Тестовая",
"SUBSCRIPTION_STATUS_ACTIVE": "Активна",
diff --git a/app/services/promo_group_service.py b/app/services/promo_group_service.py
index 25e89c9b..04c16579 100644
--- a/app/services/promo_group_service.py
+++ b/app/services/promo_group_service.py
@@ -35,18 +35,11 @@ async def auto_assign_promo_group_by_spent(
if not target_group or user.promo_group_id == target_group.id:
return None
- if (
- getattr(user, "auto_assigned_promo_group_id", None) is not None
- and user.auto_assigned_promo_group_id == target_group.id
- ):
- return None
-
previous_group_id = user.promo_group_id
user.promo_group_id = target_group.id
user.promo_group = target_group
user.updated_at = datetime.utcnow()
- user.auto_assigned_promo_group_id = target_group.id
await db.commit()
await db.refresh(user)
diff --git a/locales/en.json b/locales/en.json
index 3c52bd12..36b5a47e 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -114,7 +114,6 @@
"WELCOME": "\n🎉 Welcome to VPN Service!\n\nOur service provides fast and secure internet access without restrictions.\n\n🔐 Advantages:\n• High connection speed\n• Servers in different countries \n• Reliable data protection\n• 24/7 support\n\nTo get started, select interface language:\n",
"WELCOME_FALLBACK": "Welcome, {user_name}!",
"YES": "✅ Yes",
- "ADMIN_ACTION_INVALID": "Invalid action",
"ACCESS_DENIED": "❌ Access denied",
"ADMIN_MESSAGES": "📨 Broadcasts",
"ADMIN_MONITORING": "🔍 Monitoring",
@@ -217,7 +216,7 @@
"ADMIN_PROMO_GROUP_CREATE_TRAFFIC_PROMPT": "Enter traffic discount (0-100):",
"ADMIN_PROMO_GROUP_CREATE_SERVERS_PROMPT": "Enter server discount (0-100):",
"ADMIN_PROMO_GROUP_CREATE_DEVICES_PROMPT": "Enter device discount (0-100):",
- "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Enable automatic assignment by total spending?",
+ "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Enable automatic assignment by total spending? (yes/no)",
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_THRESHOLD_PROMPT": "Enter the spending amount in RUB required for automatic assignment:",
"ADMIN_PROMO_GROUP_INVALID_PERCENT": "Enter a number from 0 to 100.",
"ADMIN_PROMO_GROUP_INVALID_BOOL": "Please answer \"yes\" or \"no\".",
diff --git a/locales/ru.json b/locales/ru.json
index c3e8f9bd..75480f09 100644
--- a/locales/ru.json
+++ b/locales/ru.json
@@ -104,7 +104,7 @@
"ADMIN_PROMO_GROUP_CREATE_TRAFFIC_PROMPT": "Введите скидку на трафик (0-100):",
"ADMIN_PROMO_GROUP_CREATE_SERVERS_PROMPT": "Введите скидку на серверы (0-100):",
"ADMIN_PROMO_GROUP_CREATE_DEVICES_PROMPT": "Введите скидку на устройства (0-100):",
- "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Включить автоматическое назначение по сумме трат?",
+ "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Включить автоматическое назначение по сумме трат? (да/нет)",
"ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_THRESHOLD_PROMPT": "Введите сумму трат в рублях для автоматического назначения:",
"ADMIN_PROMO_GROUP_INVALID_PERCENT": "Введите число от 0 до 100.",
"ADMIN_PROMO_GROUP_INVALID_BOOL": "Введите «да» или «нет».",
@@ -334,7 +334,6 @@
"WELCOME": "\n🎉 Добро пожаловать в VPN сервис!\n\nНаш сервис предоставляет быстрый и безопасный доступ к интернету без ограничений.\n\n🔐 Преимущества:\n• Высокая скорость подключения\n• Серверы в разных странах\n• Надежная защита данных\n• Круглосуточная поддержка\n\nДля начала работы выберите язык интерфейса:\n",
"WELCOME_FALLBACK": "Добро пожаловать, {user_name}!",
"YES": "✅ Да",
- "ADMIN_ACTION_INVALID": "Недопустимое действие",
"SUBSCRIPTION_STATUS_EXPIRED": "Истекла",
"SUBSCRIPTION_STATUS_TRIAL": "Тестовая",
"SUBSCRIPTION_STATUS_ACTIVE": "Активна",
diff --git a/migrations/alembic/versions/3e6c4d6db780_add_auto_assigned_promo_group_to_users.py b/migrations/alembic/versions/3e6c4d6db780_add_auto_assigned_promo_group_to_users.py
deleted file mode 100644
index a75f2077..00000000
--- a/migrations/alembic/versions/3e6c4d6db780_add_auto_assigned_promo_group_to_users.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""Add auto assigned promo group tracking to users
-
-Revision ID: 3e6c4d6db780
-Revises: b6b5c77e2a9d
-Create Date: 2024-05-06 00:00:00.000000
-"""
-
-from typing import Sequence, Union
-
-from alembic import op
-import sqlalchemy as sa
-
-
-revision: str = "3e6c4d6db780"
-down_revision: Union[str, None] = "b6b5c77e2a9d"
-branch_labels: Union[str, Sequence[str], None] = None
-depends_on: Union[str, Sequence[str], None] = None
-
-USERS_TABLE = "users"
-COLUMN_NAME = "auto_assigned_promo_group_id"
-PROMO_GROUPS_TABLE = "promo_groups"
-
-
-def upgrade() -> None:
- bind = op.get_bind()
- inspector = sa.inspect(bind)
-
- if USERS_TABLE not in inspector.get_table_names():
- return
-
- if COLUMN_NAME in [column["name"] for column in inspector.get_columns(USERS_TABLE)]:
- return
-
- op.add_column(
- USERS_TABLE,
- sa.Column(COLUMN_NAME, sa.Integer(), nullable=True),
- )
- op.create_foreign_key(
- "fk_users_auto_assigned_promo_group_id",
- USERS_TABLE,
- PROMO_GROUPS_TABLE,
- [COLUMN_NAME],
- ["id"],
- ondelete="SET NULL",
- )
-
-
-def downgrade() -> None:
- bind = op.get_bind()
- inspector = sa.inspect(bind)
-
- if USERS_TABLE not in inspector.get_table_names():
- return
-
- if COLUMN_NAME not in [column["name"] for column in inspector.get_columns(USERS_TABLE)]:
- return
-
- fk_names = [fk["name"] for fk in inspector.get_foreign_keys(USERS_TABLE)]
- if "fk_users_auto_assigned_promo_group_id" in fk_names:
- op.drop_constraint(
- "fk_users_auto_assigned_promo_group_id",
- USERS_TABLE,
- type_="foreignkey",
- )
- op.drop_column(USERS_TABLE, COLUMN_NAME)