|
17 | 17 | 'UAH': '₴' |
18 | 18 | } |
19 | 19 |
|
| 20 | +# Жесткий порядок отображения (как ты привык) |
| 21 | +DISPLAY_ORDER = [ |
| 22 | + 'Zadarma', |
| 23 | + 'DIDWW', |
| 24 | + 'Streamtele', |
| 25 | + 'Callii', |
| 26 | + 'Wazzup24 Подписка', |
| 27 | + 'Wazzup24 Баланс номера' |
| 28 | +] |
| 29 | + |
20 | 30 | @router.message(Command("balance")) |
21 | 31 | async def handle_balance_command(message: Message, session: AsyncSession): |
22 | 32 |
|
23 | 33 | response_parts = ["💰 **Текущие балансы сервисов:**"] |
24 | 34 |
|
25 | | - # 1. Загружаем ВСЕ сервисы из БД |
26 | | - stmt = select(Service).order_by(Service.id) |
| 35 | + # 1. Загружаем сервисы |
| 36 | + stmt = select(Service) |
27 | 37 | result = await session.execute(stmt) |
28 | | - services = result.scalars().all() |
29 | | - |
30 | | - if not services: |
31 | | - await message.answer("Сервисы не найдены в базе данных.") |
32 | | - return |
33 | | - |
34 | | - for service in services: |
35 | | - # Получаем красивый символ валюты |
36 | | - currency_symbol = CURRENCY_SYMBOLS.get(service.currency, service.currency or '$') |
| 38 | + services_unsorted = result.scalars().all() |
| 39 | + |
| 40 | + # Превращаем в словарь для удобной сортировки: { 'Zadarma': ServiceObj, ... } |
| 41 | + services_map = {s.name: s for s in services_unsorted} |
| 42 | + |
| 43 | + # 2. Проходимся строго по нашему списку порядка |
| 44 | + for name in DISPLAY_ORDER: |
| 45 | + service = services_map.get(name) |
| 46 | + if not service: |
| 47 | + continue # Если вдруг сервиса нет в базе, пропускаем |
| 48 | + |
| 49 | + # Получаем символ валюты |
| 50 | + sym = CURRENCY_SYMBOLS.get(service.currency, '$') |
37 | 51 |
|
38 | | - # --- Логика для API сервисов --- |
39 | | - # Если имя сервиса есть в списке API клиентов, пробуем обновить баланс |
40 | | - # НО! Wazzup у тебя разбит на две части в БД. API клиент возвращает только один баланс. |
41 | | - # Поэтому API опрашиваем только если точное совпадение имени или особая логика. |
| 52 | + # Переменные для вывода |
| 53 | + display_amount = 0.0 |
| 54 | + status_suffix = "" |
| 55 | + is_subscription = False |
42 | 56 |
|
43 | | - real_balance = None |
44 | | - is_api = False |
| 57 | + # --- ЛОГИКА ОПРЕДЕЛЕНИЯ ТИПА --- |
45 | 58 |
|
46 | | - if service.name in API_CLIENTS and SETTINGS.API_SERVICE_STATUSES.get(service.name, True): |
| 59 | + # A. Это API сервис? (Zadarma, DIDWW) |
| 60 | + if name in API_CLIENTS and SETTINGS.API_SERVICE_STATUSES.get(name, True): |
47 | 61 | try: |
48 | | - client = API_CLIENTS[service.name] |
| 62 | + client = API_CLIENTS[name] |
49 | 63 | real_balance = await client.get_balance() |
50 | 64 |
|
51 | | - # Обновляем в БД, чтобы данные были свежими |
| 65 | + # Обновляем БД |
52 | 66 | service.last_balance = real_balance |
53 | | - is_api = True |
| 67 | + await session.commit() |
| 68 | + |
| 69 | + display_amount = real_balance |
| 70 | + status_suffix = "(API)" |
54 | 71 | except Exception: |
55 | | - # Если ошибка API, используем то, что было в базе |
56 | | - real_balance = service.last_balance |
| 72 | + display_amount = service.last_balance |
| 73 | + status_suffix = "(Ошибка API)" |
| 74 | + |
| 75 | + # B. Это подписка? (Есть monthly_fee и это НЕ API сервис) |
| 76 | + # Пример: Streamtele, Wazzup24 Подписка |
| 77 | + elif service.monthly_fee and service.monthly_fee > 0: |
| 78 | + display_amount = service.monthly_fee |
| 79 | + # Формируем строку как в старом отчете: "Подписка: ₴1500.00" |
| 80 | + # Для этого suffix оставляем пустым, а префикс добавим в line |
| 81 | + is_subscription = True |
| 82 | + |
| 83 | + # C. Это обычный ручной счет? (Callii, Wazzup24 Баланс номера) |
57 | 84 | else: |
58 | | - # Для ручных сервисов (Callii, Streamtele, Wazzup Подписки) берем из БД |
59 | | - real_balance = service.last_balance |
60 | | - |
61 | | - # Сохраняем обновление в БД |
62 | | - await session.commit() |
| 85 | + display_amount = service.last_balance |
| 86 | + status_suffix = "(примерно)" |
63 | 87 |
|
64 | | - # --- Формирование строки вывода --- |
65 | | - |
66 | | - status_text = "(API)" if is_api else "(примерно)" |
67 | | - # Если это подписка (есть monthly_fee), меняем формат вывода |
68 | | - if service.monthly_fee and service.monthly_fee > 0: |
69 | | - status_text = f"Подписка: {currency_symbol}{service.monthly_fee:.2f}" |
| 88 | + # --- ФОРМИРОВАНИЕ СТРОКИ --- |
70 | 89 |
|
71 | | - line = f"• **{service.name}:** {currency_symbol}{real_balance:.2f} {status_text}" |
| 90 | + if is_subscription: |
| 91 | + # Особый формат для подписок: "• Streamtele: Подписка: ₴1500.00" |
| 92 | + # Обрати внимание: суффикса нет, слово "Подписка" внутри значения |
| 93 | + line = f"• **{name}:** Подписка: {sym}{display_amount:.2f}" |
| 94 | + else: |
| 95 | + # Стандартный формат: "• Zadarma: $0.00 (API)" |
| 96 | + line = f"• **{name}:** {sym}{display_amount:.2f} {status_suffix}" |
| 97 | + |
72 | 98 | response_parts.append(line) |
73 | 99 |
|
74 | | - # Добавляем дату следующей оплаты, если есть |
75 | | - # Приоритет: next_alert_date (для Callii) или next_monthly_alert (для подписок) |
| 100 | + # Добавляем дату (если есть) с отступом |
76 | 101 | alert_date = service.next_alert_date or service.next_monthly_alert |
77 | | - |
78 | 102 | if alert_date: |
79 | 103 | date_str = alert_date.strftime('%Y-%m-%d') |
80 | 104 | response_parts.append(f" _След. оплата:_ {date_str}") |
|
0 commit comments