Merge pull request #1574 from Fr1ngg/3fc7wf-bedolaga/update-subscription-period-menu-pricing

Hide zero price in subscription period options
This commit is contained in:
Egor
2025-10-30 03:06:34 +03:00
committed by GitHub
3 changed files with 36 additions and 17 deletions

View File

@@ -9,7 +9,10 @@ from app.config import settings, PERIOD_PRICES, TRAFFIC_PRICES
from app.localization.loader import DEFAULT_LANGUAGE
from app.localization.texts import get_texts
from app.utils.miniapp_buttons import build_miniapp_or_callback_button
from app.utils.pricing_utils import format_period_description, apply_percentage_discount
from app.utils.pricing_utils import (
format_period_description,
apply_percentage_discount,
)
from app.utils.subscription_utils import (
get_display_subscription_link,
get_happ_cryptolink_redirect_link,
@@ -1407,10 +1410,10 @@ def get_extend_subscription_keyboard(language: str = DEFAULT_LANGUAGE) -> Inline
keyboard = []
periods = [
(14, f"📅 14 дней - {settings.format_price(settings.PRICE_14_DAYS)}"),
(30, f"📅 30 дней - {settings.format_price(settings.PRICE_30_DAYS)}"),
(60, f"📅 60 дней - {settings.format_price(settings.PRICE_60_DAYS)}"),
(90, f"📅 90 дней - {settings.format_price(settings.PRICE_90_DAYS)}")
(14, texts.PERIOD_14_DAYS),
(30, texts.PERIOD_30_DAYS),
(60, texts.PERIOD_60_DAYS),
(90, texts.PERIOD_90_DAYS)
]
for days, text in periods:

View File

@@ -5,6 +5,7 @@ import logging
from typing import Any, Dict
from app.config import settings
from app.utils.pricing_utils import format_period_option_label
from app.localization.loader import (
DEFAULT_LANGUAGE,
clear_locale_cache,
@@ -30,12 +31,12 @@ def _build_dynamic_values(language: str) -> Dict[str, Any]:
if language_code == "ru":
return {
"PERIOD_14_DAYS": f"📅 14 дней - {settings.format_price(settings.PRICE_14_DAYS)}",
"PERIOD_30_DAYS": f"📅 30 дней - {settings.format_price(settings.PRICE_30_DAYS)}",
"PERIOD_60_DAYS": f"📅 60 дней - {settings.format_price(settings.PRICE_60_DAYS)}",
"PERIOD_90_DAYS": f"📅 90 дней - {settings.format_price(settings.PRICE_90_DAYS)}",
"PERIOD_180_DAYS": f"📅 180 дней - {settings.format_price(settings.PRICE_180_DAYS)}",
"PERIOD_360_DAYS": f"📅 360 дней - {settings.format_price(settings.PRICE_360_DAYS)}",
"PERIOD_14_DAYS": format_period_option_label("📅 14 дней", settings.PRICE_14_DAYS),
"PERIOD_30_DAYS": format_period_option_label("📅 30 дней", settings.PRICE_30_DAYS),
"PERIOD_60_DAYS": format_period_option_label("📅 60 дней", settings.PRICE_60_DAYS),
"PERIOD_90_DAYS": format_period_option_label("📅 90 дней", settings.PRICE_90_DAYS),
"PERIOD_180_DAYS": format_period_option_label("📅 180 дней", settings.PRICE_180_DAYS),
"PERIOD_360_DAYS": format_period_option_label("📅 360 дней", settings.PRICE_360_DAYS),
"TRAFFIC_5GB": f"📊 5 ГБ - {settings.format_price(settings.PRICE_TRAFFIC_5GB)}",
"TRAFFIC_10GB": f"📊 10 ГБ - {settings.format_price(settings.PRICE_TRAFFIC_10GB)}",
"TRAFFIC_25GB": f"📊 25 ГБ - {settings.format_price(settings.PRICE_TRAFFIC_25GB)}",
@@ -55,12 +56,12 @@ def _build_dynamic_values(language: str) -> Dict[str, Any]:
if language_code == "en":
return {
"PERIOD_14_DAYS": f"📅 14 days - {settings.format_price(settings.PRICE_14_DAYS)}",
"PERIOD_30_DAYS": f"📅 30 days - {settings.format_price(settings.PRICE_30_DAYS)}",
"PERIOD_60_DAYS": f"📅 60 days - {settings.format_price(settings.PRICE_60_DAYS)}",
"PERIOD_90_DAYS": f"📅 90 days - {settings.format_price(settings.PRICE_90_DAYS)}",
"PERIOD_180_DAYS": f"📅 180 days - {settings.format_price(settings.PRICE_180_DAYS)}",
"PERIOD_360_DAYS": f"📅 360 days - {settings.format_price(settings.PRICE_360_DAYS)}",
"PERIOD_14_DAYS": format_period_option_label("📅 14 days", settings.PRICE_14_DAYS),
"PERIOD_30_DAYS": format_period_option_label("📅 30 days", settings.PRICE_30_DAYS),
"PERIOD_60_DAYS": format_period_option_label("📅 60 days", settings.PRICE_60_DAYS),
"PERIOD_90_DAYS": format_period_option_label("📅 90 days", settings.PRICE_90_DAYS),
"PERIOD_180_DAYS": format_period_option_label("📅 180 days", settings.PRICE_180_DAYS),
"PERIOD_360_DAYS": format_period_option_label("📅 360 days", settings.PRICE_360_DAYS),
"TRAFFIC_5GB": f"📊 5 GB - {settings.format_price(settings.PRICE_TRAFFIC_5GB)}",
"TRAFFIC_10GB": f"📊 10 GB - {settings.format_price(settings.PRICE_TRAFFIC_10GB)}",
"TRAFFIC_25GB": f"📊 25 GB - {settings.format_price(settings.PRICE_TRAFFIC_25GB)}",

View File

@@ -313,6 +313,21 @@ def format_period_description(days: int, language: str = "ru") -> str:
return f"{days} days ({months} {month_word})"
def format_period_option_label(label: str, price: int) -> str:
"""Return a period option label with price when it's greater than zero.
When the price is zero or negative, the price suffix is omitted so that the
option does not misleadingly show "0" as the cost of the period. This keeps
the UI consistent when pricing is calculated dynamically based on other
parameters such as servers or devices.
"""
if price and price > 0:
return f"{label} - {settings.format_price(price)}"
return label
def validate_pricing_calculation(
base_price: int,
monthly_additions: int,