Ошибка: код итерировал по строке "14,30,60,90,180,360" посимвольно,
что приводило к ValueError: invalid literal for int() with base 10: ','
Заменено на settings.get_available_subscription_periods() который
корректно парсит строку в список [14, 30, 60, 90, 180, 360].
1. app/keyboards/inline.py
- Добавлен параметр callback_data: str = "back_to_menu" в get_back_keyboard()
- Позволяет использовать кнопку "Назад" с разными callback'ами
2. app/services/admin_notification_service.py
- Добавлен тип "modem" в update_types с заголовком "📡 ИЗМЕНЕНИЕ МОД
ПРОБЛЕМА:
При таймауте после успешной авторизации чек мог быть создан на сервере
nalog.ru, но ответ не возвращался. Бот добавлял чек в очередь повторной
отправки → создавался дубликат.
РЕШЕНИЕ:
1. Разделена обработка ошибок на два этапа:
- Аутентификация не прошла → чек точно не создан → в очередь
- Таймаут при создании → чек МОГ быть создан → НЕ в очередь
2. Новая очередь `nalogo:pending_verification` для чеков требующих
ручной проверки (когда таймаут после успешной авторизации)
3. Кнопка в админке: Мониторинг → Статистика → "⚠️ Проверить (N)"
- Показывает список чеков с суммой, датой, payment_id
- "✅ Создан" — чек найден в налоговой, убираем из очереди
- "🔄 Отправить" — чек НЕ найден, отправляем повторно
- "🗑 Очистить всё" — после полной сверки с lknpd.nalog.ru
4. Таймаут увеличен с 10 до 30 секунд (NALOGO_TIMEOUT)
5. Атомарная защита от race condition через cache.setnx()
Изменённые файлы:
- app/utils/cache.py — добавлен метод setnx()
- app/services/nalogo_service.py — разделение ошибок, pending_verification
- app/services/nalogo_queue_service.py — статус pending в get_status()
- app/handlers/admin/monitoring.py — UI для ручной проверки
Исправленные файлы:
1. app/services/traffic_monitoring_service.py — удалены неиспользуемые импорты Decimal, aiohttp
2. app/services/blacklist_service.py — удалён неиспользуемый импорт re
3. app/database/crud/user.py:998 — создана отсутствующая функция get_users_with_active_subscriptions:
async def get_users_with_active_subscriptions(db: AsyncSession) -> List[User]:
3. Функция:
- Возвращает пользователей с активными подписками
- Фильтрует по remnawave_uuid IS NOT NULL (нужен для API Remnawave)
- Проверяет end_date > now и status == ACTIVE
app/database/crud/subscription.py:
Добавлен await db.flush() в create_subscription_no_commit для консистентности с create_user_no_commit:
db.add(subscription)
# Выполняем flush, чтобы получить присвоенный первичный ключ
await db.flush()
# Не коммитим сразу, оставляем для пакетной обработки
1. app/database/crud/subscription.py
Объединены функции create_pending_subscription и create_pending_trial_subscription:
- Добавлен параметр is_trial: bool = False в create_pending_subscription
- create_pending_trial_subscription теперь просто вызывает create_pending_subscription(is_trial=True)
- Сокращено ~75 строк дублированного кода
Удалён лишний импорт:
# Было внутри activate_pending_subscription:
from sqlalchemy import and_ # Удалено — уже импортирован на уровне модуля
2. app/handlers/subscription/purchase.py
Устранено дублирование функций:
- Удалены определения _calculate_simple_subscription_price() и _get_simple_subscription_payment_keyboard() (~75 строк)
- Добавлен импорт из app.handlers.simple_subscription
from app.handlers.simple_subscription import (
_calculate_simple_subscription_price,
_get_simple_subscription_payment_keyboard,
)
Итого сокращено: ~150 строк дублированного кода
1. app/handlers/admin/users.py
- Добавлен параметр parse_mode="HTML" в send_message для поддержки HTML-форматирования
- Добавлен вызов await state.clear() при ошибке BadRequest для очистки состояния FSM
- Добавлен get_user_by_id в импорты
- Перезагрузка user через get_user_by_id после subtract_user_balance
- Восстановление связи user_promo_groups, сбрасываемой после db.refresh() в payment-сервисах
- Добавлен мок get_user_by_id в тесте
Основные исправления:
- Фильтрация событий по дате регистрации реферала (occurred_at)
в период конкурса (start_at - end_at)
- Лидерборд теперь показывает правильные числа (было 21, стало 11)
- Разделение DEPOSIT и SUBSCRIPTION_PAYMENT в статистике:
- Основная метрика: покупки подписок (SUBSCRIPTION_PAYMENT)
- Информационно: пополнения баланса (DEPOSIT)
Новый функционал:
- Кнопка "🔍 Отладка" для просмотра транзакций конкурса
- Разбивка сумм по типам в детальной статистике
- Кнопки "Назад" в синхронизации и отладке
- Логирование дат фильтрации в синхронизации
Также исправлено:
- NaloGO: защита от дублирования чеков в очереди
(проверка nalogo:created и nalogo:queued в Redis)
Сохранение времени оплаты:
- Добавлен параметр operation_time в create_receipt()
- Чеки из очереди создаются с оригинальным временем платежа
- Парсинг created_at из Redis очереди
Защита от дублей (3 уровня):
- Проверка transaction.receipt_uuid перед созданием
- Redis ключ nalogo:created:{payment_id} с TTL 30 дней
- Сохранение receipt_uuid в транзакцию после создания
Бесконечные повторы:
- Убрано удаление чеков после 10 попыток
- Чеки остаются в очереди до успешной отправки
Обработка ошибок:
- Добавлена обработка 500 и "внутренняя ошибка" как временной недоступности
Сверка чеков:
- Заменена API сверка на сверку по логам (logs/current/payments.log)
- Кнопка "Без чеков" → "Сверка чеков" с прямым показом сверки
- Исправлена навигация кнопок "Назад"
Добавлена возможность ограничивать пользователям:
- Пополнение баланса (restriction_topup)
- Покупку/продление подписки (restriction_subscription)
Изменения:
- models.py: добавлены поля restriction_topup, restriction_subscription,
restriction_reason и property has_restrictions
- universal_migration.py: миграция для новых полей
- admin/users.py: меню управления ограничениями в карточке пользователя
- keyboards/admin.py: клавиатура ограничений с toggle-кнопками
- states.py: состояние editing_user_restriction_reason
Проверки ограничений добавлены на двух уровнях:
- start_*_payment: при выборе метода оплаты
- process_*_payment_amount: при создании платежа
Затронутые провайдеры: stars, yookassa, mulenpay, wata, pal24,
cryptobot, heleket, platega, tribute, cloudpayments
При ограничении пользователь видит причину и кнопку "Обжаловать",
ведущую на контакт поддержки из настроек.
- Добавлено восстановление описания чека из настроек при обработке очереди
- Передача telegram_user_id и amount_kopeks через всю цепочку создания чеков
- Переход на локальную исправленную версию библ