From 06c90dc3cafb8d9888e2ca6dfbb27702fbe90be0 Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 25 Sep 2025 12:51:22 +0300 Subject: [PATCH] Revert "feat: add promo group addon discount toggle" --- app/database/crud/promo_group.py | 11 +- app/database/models.py | 26 +---- app/database/universal_migration.py | 41 ------- app/handlers/admin/promo_groups.py | 159 --------------------------- app/handlers/subscription.py | 94 +++------------- app/localization/locales/en.json | 8 -- app/localization/locales/ru.json | 8 -- app/services/subscription_service.py | 16 +-- app/states.py | 2 - locales/en.json | 8 -- locales/ru.json | 8 -- 11 files changed, 20 insertions(+), 361 deletions(-) diff --git a/app/database/crud/promo_group.py b/app/database/crud/promo_group.py index 5e754056..3bc093f2 100644 --- a/app/database/crud/promo_group.py +++ b/app/database/crud/promo_group.py @@ -60,7 +60,6 @@ async def create_promo_group( device_discount_percent: int, period_discounts: Optional[Dict[int, int]] = None, auto_assign_total_spent_kopeks: Optional[int] = None, - addon_discounts_enabled: bool = True, ) -> PromoGroup: normalized_period_discounts = _normalize_period_discounts(period_discounts) @@ -70,8 +69,6 @@ async def create_promo_group( else None ) - addon_discounts_enabled = bool(addon_discounts_enabled) - promo_group = PromoGroup( name=name.strip(), server_discount_percent=max(0, min(100, server_discount_percent)), @@ -79,7 +76,6 @@ async def create_promo_group( device_discount_percent=max(0, min(100, device_discount_percent)), period_discounts=normalized_period_discounts or None, auto_assign_total_spent_kopeks=auto_assign_total_spent_kopeks, - addon_discounts_enabled=addon_discounts_enabled, is_default=False, ) @@ -88,15 +84,13 @@ async def create_promo_group( await db.refresh(promo_group) logger.info( - "Создана промогруппа '%s' с скидками (servers=%s%%, traffic=%s%%, devices=%s%%, periods=%s)" - " и порогом автоприсвоения %s₽ (скидки на доп. услуги: %s)", + "Создана промогруппа '%s' с скидками (servers=%s%%, traffic=%s%%, devices=%s%%, periods=%s) и порогом автоприсвоения %s₽", promo_group.name, promo_group.server_discount_percent, promo_group.traffic_discount_percent, promo_group.device_discount_percent, normalized_period_discounts, (auto_assign_total_spent_kopeks or 0) / 100, - addon_discounts_enabled, ) return promo_group @@ -112,7 +106,6 @@ async def update_promo_group( device_discount_percent: Optional[int] = None, period_discounts: Optional[Dict[int, int]] = None, auto_assign_total_spent_kopeks: Optional[int] = None, - addon_discounts_enabled: Optional[bool] = None, ) -> PromoGroup: if name is not None: group.name = name.strip() @@ -127,8 +120,6 @@ async def update_promo_group( group.period_discounts = normalized_period_discounts or None if auto_assign_total_spent_kopeks is not None: group.auto_assign_total_spent_kopeks = max(0, auto_assign_total_spent_kopeks) - if addon_discounts_enabled is not None: - group.addon_discounts_enabled = bool(addon_discounts_enabled) await db.commit() await db.refresh(group) diff --git a/app/database/models.py b/app/database/models.py index 9992e1c2..0a3ad865 100644 --- a/app/database/models.py +++ b/app/database/models.py @@ -292,7 +292,6 @@ class PromoGroup(Base): device_discount_percent = Column(Integer, nullable=False, default=0) period_discounts = Column(JSON, nullable=True, default=dict) auto_assign_total_spent_kopeks = Column(Integer, nullable=True, default=None) - addon_discounts_enabled = Column(Boolean, nullable=False, default=True) is_default = Column(Boolean, nullable=False, default=False) created_at = Column(DateTime, default=func.now()) updated_at = Column(DateTime, default=func.now(), onupdate=func.now()) @@ -347,16 +346,7 @@ class PromoGroup(Base): return 0 - def get_discount_percent( - self, - category: str, - period_days: Optional[int] = None, - *, - for_addon: bool = False, - ) -> int: - if for_addon and category != "period" and not self.addon_discounts_enabled: - return 0 - + def get_discount_percent(self, category: str, period_days: Optional[int] = None) -> int: if category == "period": return max(0, min(100, self._get_period_discount(period_days))) @@ -414,20 +404,10 @@ class User(Base): parts = [self.first_name, self.last_name] return " ".join(filter(None, parts)) or self.username or f"ID{self.telegram_id}" - def get_promo_discount( - self, - category: str, - period_days: Optional[int] = None, - *, - for_addon: bool = False, - ) -> int: + def get_promo_discount(self, category: str, period_days: Optional[int] = None) -> int: if not self.promo_group: return 0 - return self.promo_group.get_discount_percent( - category, - period_days, - for_addon=for_addon, - ) + return self.promo_group.get_discount_percent(category, period_days) def add_balance(self, kopeks: int) -> None: self.balance_kopeks += kopeks diff --git a/app/database/universal_migration.py b/app/database/universal_migration.py index d8beea07..b123c750 100644 --- a/app/database/universal_migration.py +++ b/app/database/universal_migration.py @@ -931,44 +931,6 @@ async def ensure_promo_groups_setup(): "Добавлена колонка promo_groups.auto_assign_total_spent_kopeks" ) - addon_discounts_column_exists = await check_column_exists( - "promo_groups", "addon_discounts_enabled" - ) - - if not addon_discounts_column_exists: - if db_type == "sqlite": - await conn.execute( - text( - "ALTER TABLE promo_groups ADD COLUMN addon_discounts_enabled BOOLEAN NOT NULL DEFAULT 1" - ) - ) - await conn.execute( - text( - "UPDATE promo_groups SET addon_discounts_enabled = 1 WHERE addon_discounts_enabled IS NULL" - ) - ) - elif db_type == "postgresql": - await conn.execute( - text( - "ALTER TABLE promo_groups ADD COLUMN addon_discounts_enabled BOOLEAN NOT NULL DEFAULT TRUE" - ) - ) - elif db_type == "mysql": - await conn.execute( - text( - "ALTER TABLE promo_groups ADD COLUMN addon_discounts_enabled TINYINT(1) NOT NULL DEFAULT 1" - ) - ) - else: - logger.error( - f"Неподдерживаемый тип БД для promo_groups.addon_discounts_enabled: {db_type}" - ) - return False - - logger.info( - "Добавлена колонка promo_groups.addon_discounts_enabled" - ) - column_exists = await check_column_exists("users", "promo_group_id") if not column_exists: @@ -2032,7 +1994,6 @@ async def check_migration_status(): "users_promo_group_column": False, "promo_groups_period_discounts_column": False, "promo_groups_auto_assign_column": False, - "promo_groups_addon_discounts_column": False, "users_auto_promo_group_assigned_column": False, "subscription_crypto_link_column": False, } @@ -2050,7 +2011,6 @@ async def check_migration_status(): status["users_promo_group_column"] = await check_column_exists('users', 'promo_group_id') status["promo_groups_period_discounts_column"] = await check_column_exists('promo_groups', 'period_discounts') status["promo_groups_auto_assign_column"] = await check_column_exists('promo_groups', 'auto_assign_total_spent_kopeks') - status["promo_groups_addon_discounts_column"] = await check_column_exists('promo_groups', 'addon_discounts_enabled') status["users_auto_promo_group_assigned_column"] = await check_column_exists('users', 'auto_promo_group_assigned') status["subscription_crypto_link_column"] = await check_column_exists('subscriptions', 'subscription_crypto_link') @@ -2088,7 +2048,6 @@ async def check_migration_status(): "users_promo_group_column": "Колонка promo_group_id у пользователей", "promo_groups_period_discounts_column": "Колонка period_discounts у промо-групп", "promo_groups_auto_assign_column": "Колонка auto_assign_total_spent_kopeks у промо-групп", - "promo_groups_addon_discounts_column": "Колонка addon_discounts_enabled у промо-групп", "users_auto_promo_group_assigned_column": "Флаг автоназначения промогруппы у пользователей", "subscription_crypto_link_column": "Колонка subscription_crypto_link в subscriptions", } diff --git a/app/handlers/admin/promo_groups.py b/app/handlers/admin/promo_groups.py index a8a853d7..917f673f 100644 --- a/app/handlers/admin/promo_groups.py +++ b/app/handlers/admin/promo_groups.py @@ -190,21 +190,6 @@ def _format_auto_assign_line(texts, group: PromoGroup) -> str: ).format(amount=amount) -def _format_addon_discount_line(texts, group: PromoGroup) -> str: - enabled = getattr(group, "addon_discounts_enabled", True) - key = ( - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_ENABLED" - if enabled - else "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_DISABLED" - ) - default = ( - "Скидки на доп. услуги: включены" - if enabled - else "Скидки на доп. услуги: отключены" - ) - return texts.t(key, default) - - def _format_auto_assign_value(value_kopeks: Optional[int]) -> str: if not value_kopeks or value_kopeks <= 0: return "0" @@ -238,20 +223,6 @@ def _parse_auto_assign_threshold_input(value: str) -> int: return max(0, kopeks) -def _parse_addon_discount_input(value: str) -> bool: - normalized = (value or "").strip().lower() - - truthy = {"1", "true", "on", "yes", "да", "вкл", "y"} - falsy = {"0", "false", "off", "no", "нет", "выкл", "n"} - - if normalized in truthy: - return True - if normalized in falsy: - return False - - raise ValueError - - async def _prompt_for_auto_assign_threshold( message: types.Message, state: FSMContext, @@ -273,27 +244,6 @@ async def _prompt_for_auto_assign_threshold( await message.answer(prompt_text) -async def _prompt_for_addon_discount( - message: types.Message, - state: FSMContext, - prompt_key: str, - default_text: str, - *, - current_value: Optional[str] = None, -): - data = await state.get_data() - texts = get_texts(data.get("language", "ru")) - prompt_text = texts.t(prompt_key, default_text) - - if current_value is not None: - try: - prompt_text = prompt_text.format(current=current_value) - except KeyError: - pass - - await message.answer(prompt_text) - - def _build_edit_menu_content( texts, group: PromoGroup, @@ -307,7 +257,6 @@ def _build_edit_menu_content( lines = [ header, _format_discount_line(texts, group), - _format_addon_discount_line(texts, group), _format_auto_assign_line(texts, group), ] @@ -360,15 +309,6 @@ def _build_edit_menu_content( callback_data=f"promo_group_edit_field_{group.id}_devices", ) ], - [ - types.InlineKeyboardButton( - text=texts.t( - "ADMIN_PROMO_GROUP_EDIT_FIELD_ADDON", - "💡 Скидки на доп. услуги", - ), - callback_data=f"promo_group_edit_field_{group.id}_addon", - ) - ], [ types.InlineKeyboardButton( text=texts.t( @@ -459,7 +399,6 @@ async def show_promo_groups_menu( group_lines = [ f"{'⭐' if group.is_default else '🎯'} {group.name}{default_suffix}", _format_discount_line(texts, group), - _format_addon_discount_line(texts, group), _format_auto_assign_line(texts, group), texts.t( "ADMIN_PROMO_GROUPS_MEMBERS_COUNT", @@ -736,39 +675,6 @@ async def process_create_group_period_discounts( return await state.update_data(new_group_period_discounts=period_discounts) - await state.set_state(AdminStates.creating_promo_group_addon_discounts) - - await _prompt_for_addon_discount( - message, - state, - "ADMIN_PROMO_GROUP_CREATE_ADDON_PROMPT", - "Включить скидки на доп. услуги при докупке? Отправьте 1 для включения или 0 для отключения.", - ) - - -@admin_required -@error_handler -async def process_create_group_addon_discounts( - message: types.Message, - state: FSMContext, - db_user, - db: AsyncSession, -): - data = await state.get_data() - texts = get_texts(data.get("language", db_user.language)) - - try: - addon_enabled = _parse_addon_discount_input(message.text) - except ValueError: - await message.answer( - texts.t( - "ADMIN_PROMO_GROUP_INVALID_ADDON", - "Введите 1, чтобы включить скидки, или 0, чтобы отключить.", - ) - ) - return - - await state.update_data(new_group_addon_discounts=addon_enabled) await state.set_state(AdminStates.creating_promo_group_auto_assign) await _prompt_for_auto_assign_threshold( @@ -810,7 +716,6 @@ async def process_create_group_auto_assign( device_discount_percent=data["new_group_devices"], period_discounts=data.get("new_group_period_discounts"), auto_assign_total_spent_kopeks=auto_assign_kopeks, - addon_discounts_enabled=data.get("new_group_addon_discounts", True), ) except Exception as e: logger.error(f"Не удалось создать промогруппу: {e}") @@ -914,12 +819,6 @@ async def prompt_edit_promo_group_field( "ADMIN_PROMO_GROUP_EDIT_DEVICES_PROMPT", "Введите новую скидку на устройства (текущее значение: {current}%):", ).format(current=group.device_discount_percent) - elif field == "addon": - await state.set_state(AdminStates.editing_promo_group_addon_discounts) - prompt = texts.t( - "ADMIN_PROMO_GROUP_EDIT_ADDON_PROMPT", - "Отправьте 1 для включения скидок на доп. услуги или 0 для отключения. Сейчас: {current}.", - ).format(current=_format_addon_discount_line(texts, group)) elif field == "periods": await state.set_state(AdminStates.editing_promo_group_period_discount) current_discounts = _normalize_periods_dict(getattr(group, "period_discounts", None)) @@ -1045,56 +944,6 @@ async def process_edit_group_servers( ) -@admin_required -@error_handler -async def process_edit_group_addon_discounts( - message: types.Message, - state: FSMContext, - db_user, - db: AsyncSession, -): - data = await state.get_data() - texts = get_texts(data.get("language", db_user.language)) - - try: - addon_enabled = _parse_addon_discount_input(message.text) - except ValueError: - await message.answer( - texts.t( - "ADMIN_PROMO_GROUP_INVALID_ADDON", - "Введите 1, чтобы включить скидки, или 0, чтобы отключить.", - ) - ) - return - - group = await get_promo_group_by_id(db, data.get("edit_group_id")) - if not group: - await message.answer("❌ Промогруппа не найдена") - await state.clear() - return - - group = await update_promo_group( - db, - group, - addon_discounts_enabled=addon_enabled, - ) - await state.set_state(AdminStates.editing_promo_group_menu) - - success_key = ( - "ADMIN_PROMO_GROUP_ADDON_ENABLED_SUCCESS" - if addon_enabled - else "ADMIN_PROMO_GROUP_ADDON_DISABLED_SUCCESS" - ) - - await _send_edit_menu_after_update( - message, - texts, - group, - data.get("language", db_user.language), - texts.t(success_key, "Скидки на доп. услуги обновлены."), - ) - - @admin_required @error_handler async def process_edit_group_devices( @@ -1386,10 +1235,6 @@ def register_handlers(dp: Dispatcher): process_create_group_period_discounts, AdminStates.creating_promo_group_period_discount, ) - dp.message.register( - process_create_group_addon_discounts, - AdminStates.creating_promo_group_addon_discounts, - ) dp.message.register( process_create_group_auto_assign, AdminStates.creating_promo_group_auto_assign, @@ -1404,10 +1249,6 @@ def register_handlers(dp: Dispatcher): process_edit_group_servers, AdminStates.editing_promo_group_server_discount, ) - dp.message.register( - process_edit_group_addon_discounts, - AdminStates.editing_promo_group_addon_discounts, - ) dp.message.register( process_edit_group_devices, AdminStates.editing_promo_group_device_discount, diff --git a/app/handlers/subscription.py b/app/handlers/subscription.py index 103c93a5..97b91d0b 100644 --- a/app/handlers/subscription.py +++ b/app/handlers/subscription.py @@ -1251,11 +1251,7 @@ async def apply_countries_changes( db: AsyncSession, state: FSMContext ): - from app.utils.pricing_utils import ( - get_remaining_months, - calculate_prorated_price, - apply_percentage_discount, - ) + from app.utils.pricing_utils import get_remaining_months, calculate_prorated_price logger.info(f"🔧 Применение изменений стран") @@ -1296,38 +1292,23 @@ async def apply_countries_changes( cost_per_month = 0 added_names = [] removed_names = [] - + added_server_prices = [] - servers_discount_percent = db_user.get_promo_discount( - "servers", - for_addon=True, - ) - discounted_prices_by_uuid: Dict[str, int] = {} - + for country in countries: if country['uuid'] in added: server_price_per_month = country['price_kopeks'] - discounted_per_month = server_price_per_month - if servers_discount_percent: - discounted_per_month, _ = apply_percentage_discount( - server_price_per_month, - servers_discount_percent, - ) - discounted_prices_by_uuid[country['uuid']] = discounted_per_month - cost_per_month += discounted_per_month + cost_per_month += server_price_per_month added_names.append(country['name']) if country['uuid'] in removed: removed_names.append(country['name']) - + total_cost, charged_months = calculate_prorated_price(cost_per_month, subscription.end_date) - + for country in countries: if country['uuid'] in added: - discounted_per_month = discounted_prices_by_uuid.get( - country['uuid'], - country['price_kopeks'], - ) - server_total_price = discounted_per_month * charged_months + server_price_per_month = country['price_kopeks'] + server_total_price = server_price_per_month * charged_months added_server_prices.append(server_total_price) logger.info(f"Стоимость новых серверов: {cost_per_month/100}₽/мес × {charged_months} мес = {total_cost/100}₽") @@ -1512,11 +1493,7 @@ async def confirm_change_devices( db_user: User, db: AsyncSession ): - from app.utils.pricing_utils import ( - get_remaining_months, - calculate_prorated_price, - apply_percentage_discount, - ) + from app.utils.pricing_utils import get_remaining_months, calculate_prorated_price new_devices_count = int(callback.data.split('_')[2]) texts = get_texts(db_user.language) @@ -1547,15 +1524,6 @@ async def confirm_change_devices( chargeable_devices = additional_devices devices_price_per_month = chargeable_devices * settings.PRICE_PER_DEVICE - devices_discount_percent = db_user.get_promo_discount( - "devices", - for_addon=True, - ) - if devices_discount_percent: - devices_price_per_month, _ = apply_percentage_discount( - devices_price_per_month, - devices_discount_percent, - ) price, charged_months = calculate_prorated_price(devices_price_per_month, subscription.end_date) if price > 0 and db_user.balance_kopeks < price: @@ -1616,11 +1584,7 @@ async def execute_change_devices( db_user: User, db: AsyncSession ): - from app.utils.pricing_utils import ( - get_remaining_months, - calculate_prorated_price, - apply_percentage_discount, - ) + from app.utils.pricing_utils import get_remaining_months, calculate_prorated_price callback_parts = callback.data.split('_') new_devices_count = int(callback_parts[3]) @@ -2156,7 +2120,7 @@ async def confirm_add_devices( db_user: User, db: AsyncSession ): - from app.utils.pricing_utils import get_remaining_months, apply_percentage_discount + from app.utils.pricing_utils import get_remaining_months, calculate_prorated_price devices_count = int(callback.data.split('_')[2]) texts = get_texts(db_user.language) @@ -2175,15 +2139,6 @@ async def confirm_add_devices( return devices_price_per_month = devices_count * settings.PRICE_PER_DEVICE - devices_discount_percent = db_user.get_promo_discount( - "devices", - for_addon=True, - ) - if devices_discount_percent: - devices_price_per_month, _ = apply_percentage_discount( - devices_price_per_month, - devices_discount_percent, - ) price, charged_months = calculate_prorated_price(devices_price_per_month, subscription.end_date) logger.info(f"Добавление {devices_count} устройств: {devices_price_per_month/100}₽/мес × {charged_months} мес = {price/100}₽") @@ -3541,20 +3496,12 @@ async def add_traffic( if settings.is_traffic_fixed(): await callback.answer("⚠️ В текущем режиме трафик фиксированный", show_alert=True) return - + traffic_gb = int(callback.data.split('_')[2]) texts = get_texts(db_user.language) subscription = db_user.subscription - + price = settings.get_traffic_price(traffic_gb) - traffic_discount_percent = db_user.get_promo_discount( - "traffic", - for_addon=True, - ) - if traffic_discount_percent: - from app.utils.pricing_utils import apply_percentage_discount - - price, _ = apply_percentage_discount(price, traffic_discount_percent) if price == 0 and traffic_gb != 0: await callback.answer("⚠️ Цена для этого пакета не настроена", show_alert=True) @@ -4953,7 +4900,7 @@ async def confirm_switch_traffic( db_user: User, db: AsyncSession ): - from app.utils.pricing_utils import get_remaining_months, apply_percentage_discount + from app.utils.pricing_utils import get_remaining_months, calculate_prorated_price new_traffic_gb = int(callback.data.split('_')[2]) texts = get_texts(db_user.language) @@ -4967,19 +4914,6 @@ async def confirm_switch_traffic( old_price_per_month = settings.get_traffic_price(current_traffic) new_price_per_month = settings.get_traffic_price(new_traffic_gb) - traffic_discount_percent = db_user.get_promo_discount( - "traffic", - for_addon=True, - ) - if traffic_discount_percent: - old_price_per_month, _ = apply_percentage_discount( - old_price_per_month, - traffic_discount_percent, - ) - new_price_per_month, _ = apply_percentage_discount( - new_price_per_month, - traffic_discount_percent, - ) months_remaining = get_remaining_months(subscription.end_date) price_difference_per_month = new_price_per_month - old_price_per_month diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json index 477d8c05..98b41a5b 100644 --- a/app/localization/locales/en.json +++ b/app/localization/locales/en.json @@ -163,22 +163,14 @@ "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_ADDON_PROMPT": "Enable discounts for add-on services? Send 1 to enable or 0 to disable.", "ADMIN_PROMO_GROUP_INVALID_PERCENT": "Enter a number from 0 to 100.", - "ADMIN_PROMO_GROUP_INVALID_ADDON": "Send 1 to enable discounts or 0 to disable them.", "ADMIN_PROMO_GROUP_CREATED": "Promo group “{name}” created.", "ADMIN_PROMO_GROUP_CREATED_BACK_BUTTON": "↩️ Back to promo groups", "ADMIN_PROMO_GROUP_EDIT_NAME_PROMPT": "Enter a new name (current: {name}):", "ADMIN_PROMO_GROUP_EDIT_TRAFFIC_PROMPT": "Enter new traffic discount (0-100):", "ADMIN_PROMO_GROUP_EDIT_SERVERS_PROMPT": "Enter new server discount (0-100):", "ADMIN_PROMO_GROUP_EDIT_DEVICES_PROMPT": "Enter new device discount (0-100):", - "ADMIN_PROMO_GROUP_EDIT_FIELD_ADDON": "💡 Add-on service discounts", - "ADMIN_PROMO_GROUP_EDIT_ADDON_PROMPT": "Send 1 to enable add-on discounts or 0 to disable them. Current: {current}.", "ADMIN_PROMO_GROUP_UPDATED": "Promo group “{name}” updated.", - "ADMIN_PROMO_GROUP_ADDON_ENABLED_SUCCESS": "Add-on service discounts enabled.", - "ADMIN_PROMO_GROUP_ADDON_DISABLED_SUCCESS": "Add-on service discounts disabled.", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_ENABLED": "Add-on discounts: enabled", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_DISABLED": "Add-on discounts: disabled", "ADMIN_PROMO_GROUP_MEMBERS_TITLE": "👥 Members of {name}", "ADMIN_PROMO_GROUP_MEMBERS_EMPTY": "This group has no members yet.", "ADMIN_PROMO_GROUP_DELETE_FORBIDDEN": "The default promo group cannot be deleted.", diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json index 940db090..831a55d1 100644 --- a/app/localization/locales/ru.json +++ b/app/localization/locales/ru.json @@ -40,22 +40,14 @@ "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_ADDON_PROMPT": "Включить скидки на доп. услуги при докупке? Отправьте 1 для включения или 0 для отключения.", "ADMIN_PROMO_GROUP_INVALID_PERCENT": "Введите число от 0 до 100.", - "ADMIN_PROMO_GROUP_INVALID_ADDON": "Введите 1, чтобы включить скидки, или 0, чтобы отключить.", "ADMIN_PROMO_GROUP_CREATED": "Промогруппа «{name}» создана.", "ADMIN_PROMO_GROUP_CREATED_BACK_BUTTON": "↩️ К промогруппам", "ADMIN_PROMO_GROUP_EDIT_NAME_PROMPT": "Введите новое название промогруппы (текущее: {name}):", "ADMIN_PROMO_GROUP_EDIT_TRAFFIC_PROMPT": "Введите новую скидку на трафик (0-100):", "ADMIN_PROMO_GROUP_EDIT_SERVERS_PROMPT": "Введите новую скидку на серверы (0-100):", "ADMIN_PROMO_GROUP_EDIT_DEVICES_PROMPT": "Введите новую скидку на устройства (0-100):", - "ADMIN_PROMO_GROUP_EDIT_FIELD_ADDON": "💡 Скидки на доп. услуги", - "ADMIN_PROMO_GROUP_EDIT_ADDON_PROMPT": "Отправьте 1 для включения скидок на доп. услуги или 0 для отключения. Сейчас: {current}.", "ADMIN_PROMO_GROUP_UPDATED": "Промогруппа «{name}» обновлена.", - "ADMIN_PROMO_GROUP_ADDON_ENABLED_SUCCESS": "Скидки на доп. услуги включены.", - "ADMIN_PROMO_GROUP_ADDON_DISABLED_SUCCESS": "Скидки на доп. услуги отключены.", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_ENABLED": "Скидки на доп. услуги: включены", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_DISABLED": "Скидки на доп. услуги: отключены", "ADMIN_PROMO_GROUP_MEMBERS_TITLE": "👥 Участники группы {name}", "ADMIN_PROMO_GROUP_MEMBERS_EMPTY": "В этой группе пока нет участников.", "ADMIN_PROMO_GROUP_DELETE_FORBIDDEN": "Базовую промогруппу нельзя удалить.", diff --git a/app/services/subscription_service.py b/app/services/subscription_service.py index 14c719da..190a9470 100644 --- a/app/services/subscription_service.py +++ b/app/services/subscription_service.py @@ -26,24 +26,15 @@ def _resolve_discount_percent( category: str, *, period_days: Optional[int] = None, - for_addon: bool = False, ) -> int: if user is not None: try: - return user.get_promo_discount( - category, - period_days, - for_addon=for_addon, - ) + return user.get_promo_discount(category, period_days) except AttributeError: pass if promo_group is not None: - return promo_group.get_discount_percent( - category, - period_days, - for_addon=for_addon, - ) + return promo_group.get_discount_percent(category, period_days) return 0 @@ -872,7 +863,6 @@ class SubscriptionService: promo_group, "traffic", period_days=period_hint_days, - for_addon=True, ) traffic_discount_per_month = traffic_price_per_month * traffic_discount_percent // 100 discounted_traffic_per_month = traffic_price_per_month - traffic_discount_per_month @@ -896,7 +886,6 @@ class SubscriptionService: promo_group, "devices", period_days=period_hint_days, - for_addon=True, ) devices_discount_per_month = devices_price_per_month * devices_discount_percent // 100 discounted_devices_per_month = devices_price_per_month - devices_discount_per_month @@ -924,7 +913,6 @@ class SubscriptionService: promo_group, "servers", period_days=period_hint_days, - for_addon=True, ) server_discount_per_month = ( server_price_per_month * servers_discount_percent // 100 diff --git a/app/states.py b/app/states.py index 9de381dd..f824f9a5 100644 --- a/app/states.py +++ b/app/states.py @@ -69,7 +69,6 @@ class AdminStates(StatesGroup): creating_promo_group_server_discount = State() creating_promo_group_device_discount = State() creating_promo_group_period_discount = State() - creating_promo_group_addon_discounts = State() creating_promo_group_auto_assign = State() editing_promo_group_menu = State() @@ -78,7 +77,6 @@ class AdminStates(StatesGroup): editing_promo_group_server_discount = State() editing_promo_group_device_discount = State() editing_promo_group_period_discount = State() - editing_promo_group_addon_discounts = State() editing_promo_group_auto_assign = State() editing_squad_price = State() diff --git a/locales/en.json b/locales/en.json index 5a151fc4..f217ed28 100644 --- a/locales/en.json +++ b/locales/en.json @@ -243,10 +243,8 @@ "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_ADDON_PROMPT": "Enable discounts for add-on services? Send 1 to enable or 0 to disable.", "ADMIN_PROMO_GROUP_CREATE_PERIOD_PROMPT": "Enter subscription period discounts (e.g. 30:10, 90:15). Send 0 if none.", "ADMIN_PROMO_GROUP_INVALID_PERCENT": "Enter a number from 0 to 100.", - "ADMIN_PROMO_GROUP_INVALID_ADDON": "Send 1 to enable discounts or 0 to disable them.", "ADMIN_PROMO_GROUP_INVALID_PERIOD_DISCOUNTS": "Enter period:discount pairs separated by commas, e.g. 30:10, 90:15, or 0.", "ADMIN_PROMO_GROUP_CREATED": "Promo group “{name}” created.", "ADMIN_PROMO_GROUP_CREATED_BACK_BUTTON": "↩️ Back to promo groups", @@ -264,17 +262,11 @@ "ADMIN_PROMO_GROUP_EDIT_FIELD_TRAFFIC": "🌐 Traffic discount", "ADMIN_PROMO_GROUP_EDIT_FIELD_SERVERS": "🖥 Server discount", "ADMIN_PROMO_GROUP_EDIT_FIELD_DEVICES": "📱 Device discount", - "ADMIN_PROMO_GROUP_EDIT_FIELD_ADDON": "💡 Add-on service discounts", "ADMIN_PROMO_GROUP_EDIT_FIELD_PERIODS": "⏳ Period discounts", "ADMIN_PROMO_GROUP_EDIT_FIELD_AUTO_ASSIGN": "🤖 Auto assignment by spending", "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Enter total spending (in ₽) required for automatic assignment. Send 0 to disable.", "ADMIN_PROMO_GROUP_INVALID_AUTO_ASSIGN": "Enter a non-negative amount in rubles or 0 to disable.", "ADMIN_PROMO_GROUP_EDIT_AUTO_ASSIGN_PROMPT": "Enter total spending (in ₽) for auto assignment. Current value: {current}.", - "ADMIN_PROMO_GROUP_EDIT_ADDON_PROMPT": "Send 1 to enable add-on discounts or 0 to disable them. Current: {current}.", - "ADMIN_PROMO_GROUP_ADDON_ENABLED_SUCCESS": "Add-on service discounts enabled.", - "ADMIN_PROMO_GROUP_ADDON_DISABLED_SUCCESS": "Add-on service discounts disabled.", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_ENABLED": "Add-on discounts: enabled", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_DISABLED": "Add-on discounts: disabled", "ADMIN_PROMO_GROUP_MEMBERS_TITLE": "👥 Members of {name}", "ADMIN_PROMO_GROUP_MEMBERS_EMPTY": "This group has no members yet.", "ADMIN_PROMO_GROUP_DELETE_FORBIDDEN": "The default promo group cannot be deleted.", diff --git a/locales/ru.json b/locales/ru.json index df20c6fb..2524c1d4 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -109,10 +109,8 @@ "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_ADDON_PROMPT": "Включить скидки на доп. услуги при докупке? Отправьте 1 для включения или 0 для отключения.", "ADMIN_PROMO_GROUP_CREATE_PERIOD_PROMPT": "Введите скидки на периоды подписки (например, 30:10, 90:15). Отправьте 0, если без скидок.", "ADMIN_PROMO_GROUP_INVALID_PERCENT": "Введите число от 0 до 100.", - "ADMIN_PROMO_GROUP_INVALID_ADDON": "Введите 1, чтобы включить скидки, или 0, чтобы отключить.", "ADMIN_PROMO_GROUP_INVALID_PERIOD_DISCOUNTS": "Введите пары период:скидка через запятую, например 30:10, 90:15, или 0.", "ADMIN_PROMO_GROUP_CREATED": "Промогруппа «{name}» создана.", "ADMIN_PROMO_GROUP_CREATED_BACK_BUTTON": "↩️ К промогруппам", @@ -130,17 +128,11 @@ "ADMIN_PROMO_GROUP_EDIT_FIELD_TRAFFIC": "🌐 Скидка на трафик", "ADMIN_PROMO_GROUP_EDIT_FIELD_SERVERS": "🖥 Скидка на серверы", "ADMIN_PROMO_GROUP_EDIT_FIELD_DEVICES": "📱 Скидка на устройства", - "ADMIN_PROMO_GROUP_EDIT_FIELD_ADDON": "💡 Скидки на доп. услуги", "ADMIN_PROMO_GROUP_EDIT_FIELD_PERIODS": "⏳ Скидки по периодам", "ADMIN_PROMO_GROUP_EDIT_FIELD_AUTO_ASSIGN": "🤖 Автовыдача по тратам", "ADMIN_PROMO_GROUP_CREATE_AUTO_ASSIGN_PROMPT": "Введите сумму общих трат (в ₽) для автоматической выдачи этой группы. Отправьте 0, чтобы отключить.", "ADMIN_PROMO_GROUP_INVALID_AUTO_ASSIGN": "Введите неотрицательное число в рублях или 0 для отключения.", "ADMIN_PROMO_GROUP_EDIT_AUTO_ASSIGN_PROMPT": "Введите сумму общих трат (в ₽) для автовыдачи. Текущее значение: {current}.", - "ADMIN_PROMO_GROUP_EDIT_ADDON_PROMPT": "Отправьте 1 для включения скидок на доп. услуги или 0 для отключения. Сейчас: {current}.", - "ADMIN_PROMO_GROUP_ADDON_ENABLED_SUCCESS": "Скидки на доп. услуги включены.", - "ADMIN_PROMO_GROUP_ADDON_DISABLED_SUCCESS": "Скидки на доп. услуги отключены.", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_ENABLED": "Скидки на доп. услуги: включены", - "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_DISABLED": "Скидки на доп. услуги: отключены", "ADMIN_PROMO_GROUP_MEMBERS_TITLE": "👥 Участники группы {name}", "ADMIN_PROMO_GROUP_MEMBERS_EMPTY": "В этой группе пока нет участников.", "ADMIN_PROMO_GROUP_DELETE_FORBIDDEN": "Базовую промогруппу нельзя удалить.",