mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-03-03 00:31:24 +00:00
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:
@@ -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:
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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\".",
|
||||
|
||||
@@ -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": "Активна",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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\".",
|
||||
|
||||
@@ -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": "Активна",
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user