diff --git a/handlers/admin/users/keyboard.py b/handlers/admin/users/keyboard.py index feda6537..642afbd7 100644 --- a/handlers/admin/users/keyboard.py +++ b/handlers/admin/users/keyboard.py @@ -356,12 +356,16 @@ def build_hwid_menu_kb(email: str, tg_id: int) -> InlineKeyboardMarkup: return builder.as_markup() -def build_key_delete_kb(tg_id: int, email: str) -> InlineKeyboardMarkup: +def build_key_delete_kb(tg_id: int) -> InlineKeyboardMarkup: builder = InlineKeyboardBuilder() builder.row( InlineKeyboardButton( text="✅ Да, удалить", - callback_data=AdminUserEditorCallback(action="users_delete_key_confirm", data=email, tg_id=tg_id).pack(), + callback_data=AdminUserEditorCallback( + action="users_delete_key_confirm", + data="ok", + tg_id=tg_id, + ).pack(), ) ) builder.row(build_editor_back_btn(tg_id)) diff --git a/handlers/admin/users/users_keys.py b/handlers/admin/users/users_keys.py index f1a18dea..2990f4c9 100644 --- a/handlers/admin/users/users_keys.py +++ b/handlers/admin/users/users_keys.py @@ -757,7 +757,10 @@ async def handle_recreate_key_confirm( IsAdminFilter(), ) async def handle_delete_key( - callback_query: CallbackQuery, callback_data: AdminUserEditorCallback, session: AsyncSession + callback_query: CallbackQuery, + callback_data: AdminUserEditorCallback, + state: FSMContext, + session: AsyncSession, ): email = callback_data.data @@ -771,22 +774,34 @@ async def handle_delete_key( ) return + await state.set_state(UserEditorState.confirm_delete_key) + await state.update_data(delete_key_email=email, delete_key_tg_id=int(callback_data.tg_id)) + await callback_query.message.edit_text( text="❓ Вы уверены, что хотите удалить ключ?", - reply_markup=build_key_delete_kb(callback_data.tg_id, email), + reply_markup=build_key_delete_kb(callback_data.tg_id), ) @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_delete_key_confirm"), + UserEditorState.confirm_delete_key, IsAdminFilter(), ) async def handle_delete_key_confirm( callback_query: types.CallbackQuery, callback_data: AdminUserEditorCallback, + state: FSMContext, session: AsyncSession, ): - email = callback_data.data + data = await state.get_data() + email = data.get("delete_key_email") + expected_tg_id = data.get("delete_key_tg_id") + await state.clear() + + if not email or int(expected_tg_id or 0) != int(callback_data.tg_id): + await callback_query.answer("Данные устарели", show_alert=True) + return result = await session.execute(select(Key.client_id).where(Key.email == email)) client_id = result.scalar_one_or_none() diff --git a/handlers/admin/users/users_manage.py b/handlers/admin/users/users_manage.py index bc327a49..a53a4065 100644 --- a/handlers/admin/users/users_manage.py +++ b/handlers/admin/users/users_manage.py @@ -107,12 +107,15 @@ async def handle_user_data_input(message: Message, state: FSMContext, session: A if message.text.isdigit(): tg_id = int(message.text) else: - username = message.text.strip().lstrip("@") - username = username.replace("https://t.me/", "") + username = message.text.strip().lstrip("@").replace("https://t.me/", "") - stmt = select(User.tg_id).where(User.username == username) - result = await session.execute(stmt) - tg_id = result.scalar_one_or_none() + stmt = ( + select(User.tg_id) + .where(func.lower(User.username) == func.lower(username)) + .order_by(User.updated_at.desc()) + .limit(1) + ) + tg_id = (await session.execute(stmt)).scalar_one_or_none() if tg_id is None: await message.answer( @@ -378,7 +381,11 @@ async def process_user_search( stmt = select( func.count(Payment.id), func.coalesce(func.sum(Payment.amount), 0), - ).where(Payment.status == "success", Payment.tg_id == tg_id) + ).where( + Payment.status == "success", + Payment.tg_id == tg_id, + Payment.payment_system != "admin", + ) result = await session.execute(stmt) topups_amount, topups_sum = result.one_or_none() or (0, 0) diff --git a/handlers/admin/users/users_states.py b/handlers/admin/users/users_states.py index 3a0ab499..96f8ed0e 100644 --- a/handlers/admin/users/users_states.py +++ b/handlers/admin/users/users_states.py @@ -14,6 +14,7 @@ class UserEditorState(StatesGroup): config_menu = State() config_select_base = State() config_input_addon = State() + confirm_delete_key = State() class RenewTariffState(StatesGroup): diff --git a/handlers/payments/utils.cpython-312-x86_64-linux-gnu.so b/handlers/payments/utils.cpython-312-x86_64-linux-gnu.so index 2298bd3d..46e0f146 100644 Binary files a/handlers/payments/utils.cpython-312-x86_64-linux-gnu.so and b/handlers/payments/utils.cpython-312-x86_64-linux-gnu.so differ