diff --git a/app/handlers/admin/promo_groups.py b/app/handlers/admin/promo_groups.py index d21b9249..414bed79 100644 --- a/app/handlers/admin/promo_groups.py +++ b/app/handlers/admin/promo_groups.py @@ -3,6 +3,7 @@ from decimal import Decimal, InvalidOperation, ROUND_HALF_UP from typing import Dict, Optional, Tuple from aiogram import Dispatcher, types, F +from aiogram.exceptions import TelegramBadRequest from aiogram.fsm.context import FSMContext from sqlalchemy.ext.asyncio import AsyncSession @@ -28,29 +29,44 @@ from app.utils.pricing_utils import format_period_description logger = logging.getLogger(__name__) -def _format_discount_line(texts, group) -> str: - return texts.t( - "ADMIN_PROMO_GROUPS_DISCOUNTS", - "Скидки — серверы: {servers}%, трафик: {traffic}%, устройства: {devices}%", - ).format( - servers=group.server_discount_percent, - traffic=group.traffic_discount_percent, - devices=group.device_discount_percent, +def _format_discount_lines(texts, group) -> Tuple[str, ...]: + header = texts.t( + "ADMIN_PROMO_GROUP_DISCOUNTS_HEADER", + "💸 Размер скидок", ) + servers_line = texts.t( + "ADMIN_PROMO_GROUP_DISCOUNTS_SERVERS", + "• Серверы: {percent}%", + ).format(percent=group.server_discount_percent) + + traffic_line = texts.t( + "ADMIN_PROMO_GROUP_DISCOUNTS_TRAFFIC", + "• Трафик: {percent}%", + ).format(percent=group.traffic_discount_percent) + + devices_line = texts.t( + "ADMIN_PROMO_GROUP_DISCOUNTS_DEVICES", + "• Устройства: {percent}%", + ).format(percent=group.device_discount_percent) + + return header, servers_line, traffic_line, devices_line + def _format_addon_discounts_line(texts, group: PromoGroup) -> str: enabled = getattr(group, "apply_discounts_to_addons", True) - if enabled: - return texts.t( - "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_ENABLED", - "Скидки на доп. услуги: включены", - ) - return texts.t( - "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_DISABLED", - "Скидки на доп. услуги: отключены", + status = texts.t( + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_ENABLED" + if enabled + else "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_DISABLED", + "включены" if enabled else "отключены", ) + return texts.t( + "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_LINE", + "• Доп. услуги: {status}", + ).format(status=status) + def _get_addon_discounts_button_text(texts, group: PromoGroup) -> str: enabled = getattr(group, "apply_discounts_to_addons", True) @@ -280,12 +296,10 @@ def _build_edit_menu_content( "✏️ Настройки промогруппы «{name}»", ).format(name=group.name) - lines = [ - header, - _format_discount_line(texts, group), - _format_addon_discounts_line(texts, group), - _format_auto_assign_line(texts, group), - ] + lines = [header] + lines.extend(_format_discount_lines(texts, group)) + lines.append(_format_addon_discounts_line(texts, group)) + lines.append(_format_auto_assign_line(texts, group)) period_lines = _format_period_discounts_lines(texts, group, language) lines.extend(period_lines) @@ -394,12 +408,22 @@ async def _send_edit_menu_after_update( ): menu_text, keyboard = _build_edit_menu_content(texts, group, language) parts = [part for part in [success_message, menu_text] if part] + text = "\n\n".join(parts) - await message.answer( - "\n\n".join(parts), - reply_markup=keyboard, - parse_mode="HTML", - ) + try: + await message.edit_text( + text, + reply_markup=keyboard, + parse_mode="HTML", + ) + except TelegramBadRequest as exc: + if "message is not modified" in str(exc).lower(): + return + await message.answer( + text, + reply_markup=keyboard, + parse_mode="HTML", + ) @admin_required @@ -431,7 +455,7 @@ async def show_promo_groups_menu( ) group_lines = [ f"{'⭐' if group.is_default else '🎯'} {group.name}{default_suffix}", - _format_discount_line(texts, group), + "\n".join(_format_discount_lines(texts, group)), _format_auto_assign_line(texts, group), texts.t( "ADMIN_PROMO_GROUPS_MEMBERS_COUNT", @@ -506,7 +530,7 @@ async def show_promo_group_details( "ADMIN_PROMO_GROUP_DETAILS_TITLE", "💳 Промогруппа: {name}", ).format(name=group.name), - _format_discount_line(texts, group), + "\n".join(_format_discount_lines(texts, group)), _format_auto_assign_line(texts, group), texts.t( "ADMIN_PROMO_GROUP_DETAILS_MEMBERS", @@ -1261,7 +1285,7 @@ async def toggle_promo_group_addon_discounts( status_text, ) - await callback.answer() + await callback.answer(status_text) def register_handlers(dp: Dispatcher): diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json index e2aa4e2a..56ef19f6 100644 --- a/app/localization/locales/en.json +++ b/app/localization/locales/en.json @@ -140,6 +140,13 @@ "ADMIN_PROMO_GROUPS_DISCOUNTS": "Discounts — servers: {servers}%, traffic: {traffic}%, devices: {devices}%", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_ENABLED": "Add-on discounts: enabled", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_DISABLED": "Add-on discounts: disabled", + "ADMIN_PROMO_GROUP_DISCOUNTS_HEADER": "💸 Discount overview", + "ADMIN_PROMO_GROUP_DISCOUNTS_SERVERS": "• Servers: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_TRAFFIC": "• Traffic: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_DEVICES": "• Devices: {percent}%", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_LINE": "• Add-on services: {status}", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_ENABLED": "enabled", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_DISABLED": "disabled", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_ENABLE": "🧩 Enable add-on discounts", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_DISABLE": "🧩 Disable add-on discounts", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_UPDATED_ENABLED": "Add-on purchase discounts have been enabled.", diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json index 669987a3..655f82c4 100644 --- a/app/localization/locales/ru.json +++ b/app/localization/locales/ru.json @@ -17,6 +17,13 @@ "ADMIN_PROMO_GROUPS_DISCOUNTS": "Скидки — серверы: {servers}%, трафик: {traffic}%, устройства: {devices}%", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_ENABLED": "Скидки на доп. услуги: включены", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_DISABLED": "Скидки на доп. услуги: отключены", + "ADMIN_PROMO_GROUP_DISCOUNTS_HEADER": "💸 Размер скидок", + "ADMIN_PROMO_GROUP_DISCOUNTS_SERVERS": "• Серверы: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_TRAFFIC": "• Трафик: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_DEVICES": "• Устройства: {percent}%", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_LINE": "• Доп. услуги: {status}", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_ENABLED": "включены", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_DISABLED": "отключены", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_ENABLE": "🧩 Включить скидки на доп. услуги", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_DISABLE": "🧩 Отключить скидки на доп. услуги", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_UPDATED_ENABLED": "Скидки на докупку доп. услуг включены.", diff --git a/locales/en.json b/locales/en.json index 110c9ae9..e0fe550c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -153,6 +153,13 @@ "ADMIN_PROMO_GROUPS_DISCOUNTS": "Discounts — servers: {servers}%, traffic: {traffic}%, devices: {devices}%", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_ENABLED": "Add-on discounts: enabled", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_DISABLED": "Add-on discounts: disabled", + "ADMIN_PROMO_GROUP_DISCOUNTS_HEADER": "💸 Discount overview", + "ADMIN_PROMO_GROUP_DISCOUNTS_SERVERS": "• Servers: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_TRAFFIC": "• Traffic: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_DEVICES": "• Devices: {percent}%", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_LINE": "• Add-on services: {status}", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_ENABLED": "enabled", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_DISABLED": "disabled", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_ENABLE": "🧩 Enable add-on discounts", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_DISABLE": "🧩 Disable add-on discounts", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_UPDATED_ENABLED": "Add-on purchase discounts have been enabled.", diff --git a/locales/ru.json b/locales/ru.json index 51eab11b..9e132fe5 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -19,6 +19,13 @@ "ADMIN_PROMO_GROUPS_DISCOUNTS": "Скидки — серверы: {servers}%, трафик: {traffic}%, устройства: {devices}%", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_ENABLED": "Скидки на доп. услуги: включены", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_DISABLED": "Скидки на доп. услуги: отключены", + "ADMIN_PROMO_GROUP_DISCOUNTS_HEADER": "💸 Размер скидок", + "ADMIN_PROMO_GROUP_DISCOUNTS_SERVERS": "• Серверы: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_TRAFFIC": "• Трафик: {percent}%", + "ADMIN_PROMO_GROUP_DISCOUNTS_DEVICES": "• Устройства: {percent}%", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNTS_LINE": "• Доп. услуги: {status}", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_ENABLED": "включены", + "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_STATUS_DISABLED": "отключены", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_ENABLE": "🧩 Включить скидки на доп. услуги", "ADMIN_PROMO_GROUP_TOGGLE_ADDON_DISCOUNT_DISABLE": "🧩 Отключить скидки на доп. услуги", "ADMIN_PROMO_GROUP_ADDON_DISCOUNT_UPDATED_ENABLED": "Скидки на докупку доп. услуг включены.",