import re from datetime import datetime from aiogram import F from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery, Message from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from database.models import Tariff from filters.admin import IsAdminFilter from .. import router from .common import ( TariffConfigState, build_cancel_config_kb, build_config_menu_kb, build_config_summary_text, ) @router.callback_query(F.data.startswith("cfg_edit_devices|"), TariffConfigState.choosing_section, IsAdminFilter()) async def ask_devices_config(callback: CallbackQuery, state: FSMContext): tariff_id = int(callback.data.split("|")[1]) await state.set_state(TariffConfigState.entering_devices) await state.update_data(tariff_id=tariff_id) text = ( "πŸ“± Настройка Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² устройств.\n\n" "Π’Π²Π΅Π΄ΠΈΡ‚Π΅ список Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² количСства устройств Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΈΠ»ΠΈ Π·Π°ΠΏΡΡ‚ΡƒΡŽ.\n" "НапримСр: 1 3 5\n\n" "Число 0 ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π±Π΅Π·Π»ΠΈΠΌΠΈΡ‚Π°.\n" "Π§Ρ‚ΠΎΠ±Ρ‹ совсСм ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π²Ρ‹Π±ΠΎΡ€ устройств ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚ Ρ‚Π°Ρ€ΠΈΡ„Π°, ΠΎΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹ΠΉ 0." ) await callback.message.edit_text(text=text, reply_markup=build_cancel_config_kb(tariff_id)) @router.message(TariffConfigState.entering_devices, IsAdminFilter()) async def save_devices_config(message: Message, state: FSMContext, session: AsyncSession): data = await state.get_data() tariff_id = data["tariff_id"] raw_text = message.text.strip() result = await session.execute(select(Tariff).where(Tariff.id == tariff_id)) tariff = result.scalar_one_or_none() if not tariff: await message.answer("❌ Π’Π°Ρ€ΠΈΡ„ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.") await state.clear() return if raw_text == "0": tariff.device_options = None else: try: parts = [p for p in re.split(r"[,\s]+", raw_text) if p.strip()] if not parts: raise ValueError values: list[int] = [] for part in parts: v = int(part) if v < 0: raise ValueError values.append(v) values = sorted(set(values)) tariff.device_options = values except Exception: await message.answer( "❌ НСкоррСктныС значСния. Π’Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ числа ΠΈΠ»ΠΈ 0 Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΈΠ»ΠΈ Π·Π°ΠΏΡΡ‚ΡƒΡŽ,\n" "Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: 1 3 5, 0 1 3 5 (0 ΠΊΠ°ΠΊ Π±Π΅Π·Π»ΠΈΠΌΠΈΡ‚)\n" "ΠΈΠ»ΠΈ 0 для ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π²Ρ‹Π±ΠΎΡ€Π° устройств.", reply_markup=build_cancel_config_kb(tariff_id), ) return tariff.updated_at = datetime.utcnow() await state.set_state(TariffConfigState.choosing_section) text = build_config_summary_text(tariff) await message.answer(text=text, reply_markup=build_config_menu_kb(tariff_id)) @router.callback_query(F.data.startswith("cfg_edit_traffic|"), TariffConfigState.choosing_section, IsAdminFilter()) async def ask_traffic_config(callback: CallbackQuery, state: FSMContext): tariff_id = int(callback.data.split("|")[1]) await state.set_state(TariffConfigState.entering_traffic) await state.update_data(tariff_id=tariff_id) text = ( "πŸ“¦ Настройка Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°.\n\n" "Π’Π²Π΅Π΄ΠΈΡ‚Π΅ список Π»ΠΈΠΌΠΈΡ‚ΠΎΠ² Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ° Π² Π“Π‘ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΈΠ»ΠΈ Π·Π°ΠΏΡΡ‚ΡƒΡŽ.\n" "НапримСр: 100 200 500\n\n" "Число 0 ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π±Π΅Π·Π»ΠΈΠΌΠΈΡ‚Π°.\n" "Π§Ρ‚ΠΎΠ±Ρ‹ совсСм ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π²Ρ‹Π±ΠΎΡ€ Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ° ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚ Ρ‚Π°Ρ€ΠΈΡ„Π°, ΠΎΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹ΠΉ 0." ) await callback.message.edit_text(text=text, reply_markup=build_cancel_config_kb(tariff_id)) @router.message(TariffConfigState.entering_traffic, IsAdminFilter()) async def save_traffic_config(message: Message, state: FSMContext, session: AsyncSession): data = await state.get_data() tariff_id = data["tariff_id"] raw_text = message.text.strip() result = await session.execute(select(Tariff).where(Tariff.id == tariff_id)) tariff = result.scalar_one_or_none() if not tariff: await message.answer("❌ Π’Π°Ρ€ΠΈΡ„ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.") await state.clear() return if raw_text == "0": tariff.traffic_options_gb = None else: try: parts = [p for p in re.split(r"[,\s]+", raw_text) if p.strip()] if not parts: raise ValueError values: list[int] = [] for part in parts: v = int(part) if v < 0: raise ValueError values.append(v) values = sorted(set(values)) tariff.traffic_options_gb = values except Exception: await message.answer( "❌ НСкоррСктныС значСния. Π’Π²Π΅Π΄ΠΈΡ‚Π΅ числа 0 ΠΈ большС Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΈΠ»ΠΈ Π·Π°ΠΏΡΡ‚ΡƒΡŽ,\n" "Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: 100 200 500.\n" "0 ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π±Π΅Π·Π»ΠΈΠΌΠΈΡ‚Π° ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ СдинствСнный 0 для ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π²Ρ‹Π±ΠΎΡ€Π°.", reply_markup=build_cancel_config_kb(tariff_id), ) return tariff.updated_at = datetime.utcnow() await state.set_state(TariffConfigState.choosing_section) text = build_config_summary_text(tariff) await message.answer(text=text, reply_markup=build_config_menu_kb(tariff_id))