feat: универсальный парсер счетов (однострочный и многострочный формат)
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
This commit is contained in:
@@ -43,11 +43,12 @@ async def add_account_command(message: Message, state: FSMContext):
|
|||||||
await state.set_state(AddAccountStates.waiting_for_data)
|
await state.set_state(AddAccountStates.waiting_for_data)
|
||||||
await message.answer(
|
await message.answer(
|
||||||
"💳 **Добавление счетов**\n\n"
|
"💳 **Добавление счетов**\n\n"
|
||||||
"Отправьте данные в формате:\n"
|
"📋 **Формат 1 (однострочный):**\n"
|
||||||
"`клубная_карта номер_счета`\n\n"
|
"`карта счет`\n"
|
||||||
"**Для одного счета:**\n"
|
"Пример: `2223 11-22-33-44-55-66-77`\n\n"
|
||||||
"`2223 11-22-33-44-55-66-77`\n\n"
|
"📋 **Формат 2 (многострочный из таблицы):**\n"
|
||||||
"**Для нескольких счетов (каждый с новой строки):**\n"
|
"Скопируйте столбцы со счетами и картами - система сама распознает\n\n"
|
||||||
|
"**Для нескольких счетов:**\n"
|
||||||
"`2223 11-22-33-44-55-66-77`\n"
|
"`2223 11-22-33-44-55-66-77`\n"
|
||||||
"`2223 88-99-00-11-22-33-44`\n"
|
"`2223 88-99-00-11-22-33-44`\n"
|
||||||
"`3334 12-34-56-78-90-12-34`\n\n"
|
"`3334 12-34-56-78-90-12-34`\n\n"
|
||||||
@@ -121,14 +122,48 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
|||||||
accounts_data = []
|
accounts_data = []
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
for i, line in enumerate(lines, 1):
|
# Универсальный парсер: поддержка однострочного и многострочного формата
|
||||||
parts = line.strip().split()
|
i = 0
|
||||||
if len(parts) != 2:
|
while i < len(lines):
|
||||||
errors.append(f"Строка {i}: неверный формат (ожидается: клубная_карта номер_счета)")
|
line = lines[i].strip()
|
||||||
|
|
||||||
|
# Пропускаем пустые строки и строки с названиями/датами
|
||||||
|
if not line or any(x in line.lower() for x in ['viposnova', '0.00', ':']):
|
||||||
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Проверяем, есть ли в строке пробел (однострочный формат: "карта счет")
|
||||||
|
if ' ' in line:
|
||||||
|
# Однострочный формат: разделяем по первому пробелу
|
||||||
|
parts = line.split(maxsplit=1)
|
||||||
|
if len(parts) == 2:
|
||||||
club_card, account_number = parts
|
club_card, account_number = parts
|
||||||
|
else:
|
||||||
|
errors.append(f"Строка {i+1}: неверный формат")
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# Многострочный формат: текущая строка - счет, следующая - карта
|
||||||
|
account_number = line
|
||||||
|
i += 1
|
||||||
|
if i >= len(lines):
|
||||||
|
errors.append(f"Строка {i}: отсутствует номер карты после счета {account_number}")
|
||||||
|
break
|
||||||
|
|
||||||
|
club_card = lines[i].strip()
|
||||||
|
# Пропускаем, если следующая строка содержит мусор
|
||||||
|
if not club_card or any(x in club_card.lower() for x in ['viposnova', '0.00', ':']):
|
||||||
|
errors.append(f"Строка {i}: некорректный номер карты после счета {account_number}")
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
club_card = lines[i].strip()
|
||||||
|
# Пропускаем, если следующая строка содержит мусор
|
||||||
|
if not club_card or any(x in club_card.lower() for x in ['viposnova', '0.00', ':']):
|
||||||
|
errors.append(f"Строка {i}: некорректный номер карты после счета {account_number}")
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Создаем счет
|
||||||
try:
|
try:
|
||||||
async with async_session_maker() as session:
|
async with async_session_maker() as session:
|
||||||
account = await AccountService.create_account(
|
account = await AccountService.create_account(
|
||||||
@@ -159,9 +194,11 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
errors.append(f"Строка {i} ({club_card} {account_number}): {str(e)}")
|
errors.append(f"Счет {account_number} (карта {club_card}): {str(e)}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errors.append(f"Строка {i}: {str(e)}")
|
errors.append(f"Счет {account_number}: {str(e)}")
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
# Формируем отчет
|
# Формируем отчет
|
||||||
text = f"📊 **Результаты добавления счетов**\n\n"
|
text = f"📊 **Результаты добавления счетов**\n\n"
|
||||||
|
|||||||
@@ -163,7 +163,8 @@ async def handle_text_message(message: Message):
|
|||||||
# Обрабатываем в зависимости от режима
|
# Обрабатываем в зависимости от режима
|
||||||
if settings.mode == 'broadcast':
|
if settings.mode == 'broadcast':
|
||||||
# Режим рассылки с планировщиком
|
# Режим рассылки с планировщиком
|
||||||
forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=message.from_user.id)
|
# НЕ исключаем отправителя - админ должен видеть все сообщения
|
||||||
|
forwarded_ids, success, fail = await broadcast_message_with_scheduler(message, exclude_user_id=None)
|
||||||
|
|
||||||
# Сохраняем сообщение в историю
|
# Сохраняем сообщение в историю
|
||||||
await ChatMessageService.save_message(
|
await ChatMessageService.save_message(
|
||||||
|
|||||||
Reference in New Issue
Block a user