Merge pull request #220 from Fr1ngg/revert-219-6eo1zk-bedolaga/add-button-selection-for-promo-group-creation

Revert "Add single-use promo group auto assignment"
This commit is contained in:
Egor
2025-09-23 04:13:18 +03:00
committed by GitHub
9 changed files with 16 additions and 151 deletions

View File

@@ -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:

View File

@@ -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():

View File

@@ -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,

View File

@@ -114,7 +114,6 @@
"WELCOME": "\n🎉 <b>Welcome to VPN Service!</b>\n\nOur service provides fast and secure internet access without restrictions.\n\n🔐 <b>Advantages:</b>\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\".",

View File

@@ -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🎉 <b>Добро пожаловать в VPN сервис!</b>\n\nНаш сервис предоставляет быстрый и безопасный доступ к интернету без ограничений.\n\n🔐 <b>Преимущества:</b>\n• Высокая скорость подключения\n• Серверы в разных странах\n• Надежная защита данных\n• Круглосуточная поддержка\n\nДля начала работы выберите язык интерфейса:\n",
"WELCOME_FALLBACK": "Добро пожаловать, {user_name}!",
"YES": "✅ Да",
"ADMIN_ACTION_INVALID": "Недопустимое действие",
"SUBSCRIPTION_STATUS_EXPIRED": "Истекла",
"SUBSCRIPTION_STATUS_TRIAL": "Тестовая",
"SUBSCRIPTION_STATUS_ACTIVE": "Активна",

View File

@@ -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)

View File

@@ -114,7 +114,6 @@
"WELCOME": "\n🎉 <b>Welcome to VPN Service!</b>\n\nOur service provides fast and secure internet access without restrictions.\n\n🔐 <b>Advantages:</b>\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\".",

View File

@@ -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🎉 <b>Добро пожаловать в VPN сервис!</b>\n\nНаш сервис предоставляет быстрый и безопасный доступ к интернету без ограничений.\n\n🔐 <b>Преимущества:</b>\n• Высокая скорость подключения\n• Серверы в разных странах\n• Надежная защита данных\n• Круглосуточная поддержка\n\nДля начала работы выберите язык интерфейса:\n",
"WELCOME_FALLBACK": "Добро пожаловать, {user_name}!",
"YES": "✅ Да",
"ADMIN_ACTION_INVALID": "Недопустимое действие",
"SUBSCRIPTION_STATUS_EXPIRED": "Истекла",
"SUBSCRIPTION_STATUS_TRIAL": "Тестовая",
"SUBSCRIPTION_STATUS_ACTIVE": "Активна",

View File

@@ -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)