feat(tariffs): configurable purchase order for periods and packages
The order of enabled_periods (period tariffs) and traffic_packages (traffic tariffs) is now the storefront order everywhere — both the Telegram keyboard and the web app. Only new tariffs-config tariffs are affected; legacy subscription/traffic options are untouched. - Stop sorting periods and traffic packages in the web app plans serializer so it follows the configured order, matching the bot keyboards that already iterate the lists as-is. - Preserve the row order through the admin draft (load and save) instead of sorting by months. - Add a reusable Sortable component to the UI library (native HTML5 drag & drop with a grip handle; bits-ui/shadcn have no such primitive) and use it to reorder period rows and traffic package rows in the tariff editor.
This commit is contained in:
@@ -495,7 +495,10 @@ def _serialize_plans(
|
||||
else [],
|
||||
}
|
||||
if tariff.billing_model == "period":
|
||||
for months in sorted(tariff.enabled_periods):
|
||||
# Render periods in the configured order (enabled_periods is the
|
||||
# source of truth for purchase-period ordering, matching the bot
|
||||
# keyboards). Do not sort so admins can reorder via drag & drop.
|
||||
for months in tariff.enabled_periods:
|
||||
price = tariff.period_price(int(months), default_currency)
|
||||
stars_price = tariff.period_price(int(months), "stars")
|
||||
if price is None and (stars_price is None or int(stars_price) <= 0):
|
||||
@@ -528,7 +531,14 @@ def _serialize_plans(
|
||||
tariff.traffic_packages.stars if tariff.traffic_packages else []
|
||||
)
|
||||
}
|
||||
for traffic_gb in sorted(set(currency_packages) | set(stars_packages)):
|
||||
# Preserve the configured package order (default-currency list first,
|
||||
# then any Stars-only volumes) so admins can reorder via drag & drop.
|
||||
# Matches the bot keyboard, which iterates the package list as-is.
|
||||
ordered_gb: List[float] = []
|
||||
for traffic_gb in list(currency_packages) + list(stars_packages):
|
||||
if traffic_gb not in ordered_gb:
|
||||
ordered_gb.append(traffic_gb)
|
||||
for traffic_gb in ordered_gb:
|
||||
price = currency_packages.get(traffic_gb)
|
||||
stars_price = stars_packages.get(traffic_gb)
|
||||
if price is None and (stars_price is None or int(stars_price) <= 0):
|
||||
|
||||
Reference in New Issue
Block a user