Add promo code toggle and activations handling in admin panel
- Implemented a new handler to toggle the active status of promo codes, allowing admins to activate or deactivate codes easily. - Added functionality to display activations for specific promo codes, enhancing visibility into their usage. - Updated localization files to include new messages related to promo status changes and activations in both English and Russian, improving admin experience.
This commit is contained in:
@@ -1016,6 +1016,110 @@ async def process_promo_edit_validity_handler(message: types.Message, state: FSM
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
@router.callback_query(F.data.startswith("promo_toggle:"))
|
||||||
|
async def promo_toggle_handler(callback: types.CallbackQuery, i18n_data: dict,
|
||||||
|
settings: Settings, session: AsyncSession):
|
||||||
|
"""Toggle promo code active status"""
|
||||||
|
current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE)
|
||||||
|
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
|
||||||
|
if not i18n or not callback.message:
|
||||||
|
await callback.answer("Error", show_alert=True)
|
||||||
|
return
|
||||||
|
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
|
||||||
|
|
||||||
|
promo_id = int(callback.data.split(":")[1])
|
||||||
|
promo = await promo_code_dal.get_promo_code_by_id(session, promo_id)
|
||||||
|
if not promo:
|
||||||
|
await callback.answer(_("admin_promo_not_found", default="Промокод не найден"), show_alert=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Toggle status
|
||||||
|
new_status = not promo.is_active
|
||||||
|
update_data = {"is_active": new_status}
|
||||||
|
|
||||||
|
updated = await promo_code_dal.update_promo_code(session, promo_id, update_data)
|
||||||
|
if updated:
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
status_text = _("admin_promo_status_activated", default="активирован") if new_status else _("admin_promo_status_deactivated", default="деактивирован")
|
||||||
|
success_text = _(
|
||||||
|
"admin_promo_toggle_success",
|
||||||
|
default="✅ Промокод <b>{code}</b> {status}",
|
||||||
|
code=promo.code,
|
||||||
|
status=status_text
|
||||||
|
)
|
||||||
|
|
||||||
|
await callback.answer(success_text, show_alert=True)
|
||||||
|
|
||||||
|
# Refresh the detail view
|
||||||
|
await promo_detail_handler(callback, i18n_data, settings, session)
|
||||||
|
else:
|
||||||
|
await session.rollback()
|
||||||
|
await callback.answer(_(
|
||||||
|
"admin_promo_toggle_failed",
|
||||||
|
default="❌ Ошибка изменения статуса промокода"
|
||||||
|
), show_alert=True)
|
||||||
|
|
||||||
|
|
||||||
|
@router.callback_query(F.data.startswith("promo_activations:"))
|
||||||
|
async def promo_activations_handler(callback: types.CallbackQuery, i18n_data: dict,
|
||||||
|
settings: Settings, session: AsyncSession):
|
||||||
|
"""Show promo code activations"""
|
||||||
|
current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE)
|
||||||
|
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
|
||||||
|
if not i18n or not callback.message:
|
||||||
|
await callback.answer("Error", show_alert=True)
|
||||||
|
return
|
||||||
|
_ = lambda key, **kwargs: i18n.gettext(current_lang, key, **kwargs)
|
||||||
|
|
||||||
|
promo_id = int(callback.data.split(":")[1])
|
||||||
|
promo = await promo_code_dal.get_promo_code_by_id(session, promo_id)
|
||||||
|
if not promo:
|
||||||
|
await callback.answer(_("admin_promo_not_found", default="Промокод не найден"), show_alert=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get activations for this promo code
|
||||||
|
activations = await promo_code_dal.get_promo_activations_by_code_id(session, promo_id)
|
||||||
|
|
||||||
|
if not activations:
|
||||||
|
text = _(
|
||||||
|
"admin_promo_no_activations",
|
||||||
|
default="📋 <b>Активации промокода: {code}</b>\n\n❌ Активаций не найдено",
|
||||||
|
code=promo.code
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
text_parts = [_(
|
||||||
|
"admin_promo_activations_header",
|
||||||
|
default="📋 <b>Активации промокода: {code}</b>\n\n",
|
||||||
|
code=promo.code
|
||||||
|
)]
|
||||||
|
|
||||||
|
for activation in activations:
|
||||||
|
activation_date = activation.created_at.strftime('%Y-%m-%d %H:%M') if activation.created_at else "N/A"
|
||||||
|
text_parts.append(_(
|
||||||
|
"admin_promo_activation_item",
|
||||||
|
default="👤 User ID: <b>{user_id}</b>\n📅 Дата: <b>{date}</b>\n",
|
||||||
|
user_id=activation.user_id,
|
||||||
|
date=activation_date
|
||||||
|
))
|
||||||
|
|
||||||
|
text = "".join(text_parts)
|
||||||
|
|
||||||
|
# Build keyboard with back button
|
||||||
|
kb = InlineKeyboardBuilder()
|
||||||
|
kb.row(
|
||||||
|
InlineKeyboardButton(
|
||||||
|
text=_("admin_promo_back_to_detail_button", default="⬅️ К промокоду"),
|
||||||
|
callback_data=f"promo_detail:{promo_id}")
|
||||||
|
)
|
||||||
|
|
||||||
|
await callback.message.edit_text(
|
||||||
|
text,
|
||||||
|
reply_markup=kb.as_markup(),
|
||||||
|
parse_mode="HTML")
|
||||||
|
await callback.answer()
|
||||||
|
|
||||||
|
|
||||||
@router.callback_query(F.data.startswith("promo_delete:"))
|
@router.callback_query(F.data.startswith("promo_delete:"))
|
||||||
async def promo_delete_handler(callback: types.CallbackQuery, i18n_data: dict,
|
async def promo_delete_handler(callback: types.CallbackQuery, i18n_data: dict,
|
||||||
settings: Settings, session: AsyncSession):
|
settings: Settings, session: AsyncSession):
|
||||||
|
|||||||
@@ -413,11 +413,19 @@
|
|||||||
"admin_promo_card_created_by": "👤 Created by: <b>{creator}</b>",
|
"admin_promo_card_created_by": "👤 Created by: <b>{creator}</b>",
|
||||||
"admin_promo_status_active": "✅ Active",
|
"admin_promo_status_active": "✅ Active",
|
||||||
"admin_promo_status_inactive": "🚫 Inactive",
|
"admin_promo_status_inactive": "🚫 Inactive",
|
||||||
|
"admin_promo_status_activated": "activated",
|
||||||
|
"admin_promo_status_deactivated": "deactivated",
|
||||||
"admin_promo_status_expired": "⏰ Expired",
|
"admin_promo_status_expired": "⏰ Expired",
|
||||||
"admin_promo_status_used_up": "🔄 Used up",
|
"admin_promo_status_used_up": "🔄 Used up",
|
||||||
"admin_promo_toggle_status_button": "🔄 On/Off",
|
"admin_promo_toggle_status_button": "🔄 On/Off",
|
||||||
"admin_promo_view_activations_button": "📋 Activations",
|
"admin_promo_view_activations_button": "📋 Activations",
|
||||||
"admin_promo_back_to_list_button": "⬅️ Back to list",
|
"admin_promo_back_to_list_button": "⬅️ Back to list",
|
||||||
|
"admin_promo_toggle_success": "✅ Promo code <b>{code}</b> {status}",
|
||||||
|
"admin_promo_toggle_failed": "❌ Error changing promo code status",
|
||||||
|
"admin_promo_no_activations": "📋 <b>Activations of promo code: {code}</b>\n\n❌ No activations found",
|
||||||
|
"admin_promo_activations_header": "📋 <b>Activations of promo code: {code}</b>\n\n",
|
||||||
|
"admin_promo_activation_item": "👤 User ID: <b>{user_id}</b>\n📅 Date: <b>{date}</b>\n",
|
||||||
|
"admin_promo_back_to_detail_button": "⬅️ Back to promo",
|
||||||
|
|
||||||
"admin_panel_online_label": "Online",
|
"admin_panel_online_label": "Online",
|
||||||
"admin_panel_active_label": "Active",
|
"admin_panel_active_label": "Active",
|
||||||
|
|||||||
@@ -412,11 +412,19 @@
|
|||||||
"admin_promo_card_created_by": "👤 Создал: <b>{creator}</b>",
|
"admin_promo_card_created_by": "👤 Создал: <b>{creator}</b>",
|
||||||
"admin_promo_status_active": "✅ Активен",
|
"admin_promo_status_active": "✅ Активен",
|
||||||
"admin_promo_status_inactive": "🚫 Неактивен",
|
"admin_promo_status_inactive": "🚫 Неактивен",
|
||||||
|
"admin_promo_status_activated": "активирован",
|
||||||
|
"admin_promo_status_deactivated": "деактивирован",
|
||||||
"admin_promo_status_expired": "⏰ Истек",
|
"admin_promo_status_expired": "⏰ Истек",
|
||||||
"admin_promo_status_used_up": "🔄 Исчерпан",
|
"admin_promo_status_used_up": "🔄 Исчерпан",
|
||||||
"admin_promo_toggle_status_button": "🔄 Вкл/Выкл",
|
"admin_promo_toggle_status_button": "🔄 Вкл/Выкл",
|
||||||
"admin_promo_view_activations_button": "📋 Активации",
|
"admin_promo_view_activations_button": "📋 Активации",
|
||||||
"admin_promo_back_to_list_button": "⬅️ К списку",
|
"admin_promo_back_to_list_button": "⬅️ К списку",
|
||||||
|
"admin_promo_toggle_success": "✅ Промокод <b>{code}</b> {status}",
|
||||||
|
"admin_promo_toggle_failed": "❌ Ошибка изменения статуса промокода",
|
||||||
|
"admin_promo_no_activations": "📋 <b>Активации промокода: {code}</b>\n\n❌ Активаций не найдено",
|
||||||
|
"admin_promo_activations_header": "📋 <b>Активации промокода: {code}</b>\n\n",
|
||||||
|
"admin_promo_activation_item": "👤 User ID: <b>{user_id}</b>\n📅 Дата: <b>{date}</b>\n",
|
||||||
|
"admin_promo_back_to_detail_button": "⬅️ К промокоду",
|
||||||
|
|
||||||
"admin_panel_online_label": "Онлайн",
|
"admin_panel_online_label": "Онлайн",
|
||||||
"admin_panel_active_label": "Активных",
|
"admin_panel_active_label": "Активных",
|
||||||
|
|||||||
Reference in New Issue
Block a user